Project

General

Profile

Download (20.1 KB) Statistics
| Branch: | Tag: | Revision:
1
<?php
2
/**
3
 * @file
4
 * Provides external links for sources to taxa information.
5
 *
6
 * @copyright
7
 *   (C) 2007-2012 EDIT
8
 *   European Distributed Institute of Taxonomy
9
 *   http://www.e-taxonomy.eu
10
 *
11
 *   The contents of this module are subject to the Mozilla
12
 *   Public License Version 1.1.
13
 * @see http://www.mozilla.org/MPL/MPL-1.1.html
14
 *
15
 * @author
16
 *   - Andreas Kohlbecker <a.kohlbecker@BGBM.org>
17
 *   - Wouter Addink <w.addink@eti.uva.nl> (migration from Drupal 5 to Drupal7)
18
 */
19

    
20
/**
21
 * Display help and module information.
22
 *
23
 * @param string $path
24
 *   For which path of the site we're displaying help.
25
 * @param array $arg
26
 *   Array that holds the current path as would be returned from arg() function.
27
 *
28
 * @return string
29
 *   Help text for the path.
30
 */
31
function ext_links_help($path, $arg) {
32
  switch ($path) {
33
    case 'admin/help#ext_links':
34
      $output = '<p>' . t("Link to external sources like ## for taxa.") . '</p>';
35
      return $output;
36
    case 'admin/config/cdm_dataportal/ext_links':
37
      $output = '<p>' . t('The external links module allows to configure URL templates for links to external data sources.');
38
      return $output;
39
    case 'admin/config/cdm_dataportal/ext_links/%':
40
      $output = '<p>' . t('An external link template.');
41
      return $output;
42
  }
43
}
44

    
45
/**
46
 * Implements hook_menu().
47
 */
48
function ext_links_menu() {
49
  $items = [];
50

    
51
  $items['admin/config/cdm_dataportal/ext_links'] = [
52
    'title' => 'External links',
53
    'description' => 'Configure external links templates.',
54
    'page callback' => 'drupal_get_form',
55
    'page arguments' => ['ext_links_admin_overview'],
56
    'access arguments' => ['access administration pages'],
57
    'file' => 'ext_links.admin.inc'
58
  ];
59
  $items['admin/config/cdm_dataportal/ext_links/list'] = [
60
    'title' => 'List',
61
    'type' => MENU_DEFAULT_LOCAL_TASK,
62
  ];
63
  $items['admin/config/cdm_dataportal/ext_links/add'] = [
64
    'title' => 'Add external link',
65
    'page callback' => 'ext_links_admin_link_template_page',
66
    'access arguments' => ['access administration pages'],
67
    'type' => MENU_LOCAL_ACTION,
68
    'weight' => 1,
69
    'file' => 'ext_links.admin.inc',
70
  ];
71
  $items['admin/config/cdm_dataportal/ext_links/appearance'] = [
72
    'title' => 'Appearance',
73
    'page callback' => 'drupal_get_form',
74
    'page arguments' => ['ext_links_admin_appearance_page'],
75
    'access arguments' => ['access administration pages'],
76
    'type' => MENU_LOCAL_TASK,
77
    'weight' => 2,
78
    'file' => 'ext_links.admin.inc',
79
  ];
80
  $items['admin/config/cdm_dataportal/ext_links/%ext_links'] = [ // %ext_links refers to ext_links_load
81
    'title' => 'Edit external link',
82
    'page callback' => 'ext_links_admin_link_template_page',
83
    'page arguments' => [4],
84
    'access arguments' => ['access administration pages'],
85
    'file' => 'ext_links.admin.inc',
86
  ];
87
  $items['admin/config/cdm_dataportal/ext_links/%ext_links/status/%'] = [
88
    'title' => 'Enable or disable external link',
89
    'page callback' => 'ext_links_admin_link_template_set_status',
90
    'page arguments' => [4, 6],
91
    'access arguments' => ['access administration pages'],
92
 //   'type' => MENU_CALLBACK,
93
    'file' => 'ext_links.admin.inc',
94
  ];
95
  $items['ext_links/category/autocomplete'] = [
96
    'title' => 'Autocomplete for external link categories',
97
    'page callback' => 'ext_links_category_autocomplete',
98
    'access arguments' => ['access administration pages'],
99
    'type' => MENU_CALLBACK
100
  ];
101
  return $items;
102
}
103

    
104
/**
105
 * Retrieves a list of External Link templates, ordered by weight.
106
 *
107
 * Empty 'ext_links' tables will be initialized with the default templates.
108
 *
109
 * @see ext_links_template_defaults()
110
 *
111
 * @param $enabled_only boolean
112
 *   When TRUE external link templates with status != null are excluded from the list.
113
 * @return array
114
 *   An array of external link template objects, keyed by the format ID and ordered by
115
 *   weight.
116
 *
117
 */
118
function ext_links_templates($enabled_only = FALSE) {
119
  global $language;
120
  $link_templates = &drupal_static(__FUNCTION__, array());
121

    
122
  // cache_clear_all("ext_links_templates:{$language->language}");
123
  // All available link_templates are cached for performance.
124
  if (!is_array($link_templates) || !count($link_templates)) {
125
    if ($cache = cache_get("ext_links:{$language->language}")) {
126
      $link_templates = $cache->data;
127
    }
128
    else {
129
      $test = false;
130
      if($test){
131
        $link_templates = [];
132
        $link_templates_arrays = ext_links_template_defaults();
133
        foreach($link_templates_arrays as $a){
134
          $link_templates[] = (object)$a;
135
        }
136
      } else {
137
        $query = db_select('ext_links', 'elt')
138
          ->addTag('translatable')
139
          ->fields('elt');
140
        if($enabled_only){
141
          $query = $query->condition('status', '1');
142
        }
143
        $link_templates =
144
          $query->orderBy('weight')
145
          ->execute()
146
          ->fetchAllAssoc('id');
147
      }
148
      if(!count($link_templates)) {
149
        $link_templates_arrays = ext_links_template_defaults();
150
        $query = db_insert('ext_links')
151
          ->fields(array_keys(array_values($link_templates_arrays)[0]));
152
        foreach($link_templates_arrays as $a){
153
          $query->values($a);
154
        }
155
        try {
156
          $query->execute();
157
        } catch (Exception $e) {
158
          drupal_set_message("Error while initializing ext_links database: " . $e->getMessage(), "error");
159
        }
160
        $link_templates = [];
161
        foreach($link_templates_arrays as $a){
162
          $link_templates[] = (object)$a;
163
        }
164
      }
165
      // cache_set("ext_links:{$language->language}", $link_templates);
166
    }
167
  }
168
  return $link_templates;
169
}
170

    
171
/**
172
 * Resets the text format caches.
173
 *
174
 * @see filter_formats()
175
 */
176
function ext_links_templates_reset() {
177
  cache_clear_all('ext_links', 'cache', TRUE);
178
  drupal_static_reset('ext_links');
179
}
180

    
181
/**
182
 * Loads a text format object from the database.
183
 *
184
 * @param $extlink_id
185
 *   The external link ID. ($link->id)
186
 *
187
 * @return
188
 *   A fully-populated text format object, if the requested format exists and
189
 *   is enabled. If the format does not exist, or exists in the database but
190
 *   has been marked as disabled, FALSE is returned.
191
 *
192
 * @see ext_links_exists()
193
 */
194
function ext_links_load($extlink_id) {
195
  $test = false;
196
  if($test) {
197
    $defaults = ext_links_template_defaults();
198
    return isset($defaults[$extlink_id]) ? (object)$defaults[$extlink_id] : FALSE;
199
  }
200
  else {
201
   $link_templates = ext_links_templates();
202
    return isset($link_templates[$extlink_id]) ? $link_templates[$extlink_id] : FALSE;
203
  }
204
}
205

    
206
/**
207
 * Saves a text format object to the database.
208
 *
209
 * @param $link_template
210
 *   A link template object having the properties:
211
 *   - id: The machine name of the external link. If this corresponds
212
 *     to an existing external link, this one will be updated;
213
 *     otherwise, a new external link will be created.
214
 *   - title: The link title
215
 *   - link: The link url template.
216
 *   - status: (optional) An integer indicating whether the ext link is
217
 *     enabled (1) or not (0). Defaults to 1.
218
 *   - weight: (optional) The weight of the external link, which controls its
219
 *     placement in external link block. If omitted, the weight is set to 0.
220
 *     Defaults to NULL.
221
 *
222
 * @return
223
 *   SAVED_NEW or SAVED_UPDATED.
224
 */
225
function ext_links_save($link_template) {
226

    
227
  $link_template->title = trim($link_template->title);
228
  $link_template->cache = true;
229
  if (!isset($link_template->status)) {
230
    $link_template->status = 1;
231
  }
232
  if (!isset($link_template->weight)) {
233
    $link_template->weight = 0;
234
  }
235

    
236
  // Insert or update the text format.
237
  $return = db_merge('ext_links')
238
    ->key(array('id' => $link_template->id))
239
    ->fields(array(
240
      'id' => $link_template->id,
241
      'title' => $link_template->title,
242
      'link' => $link_template->link,
243
      'category' => $link_template->category,
244
      'status' => (int) $link_template->status,
245
      'weight' => (int) $link_template->weight,
246
    ))
247
    ->execute();
248

    
249
  ext_links_templates_reset();
250
  return $return;
251
}
252

    
253
/**
254
 * Determines if a external link exists.
255
 *
256
 * @param $ext_link_name
257
 *   The ID of the external link to check.
258
 *
259
 * @return
260
 *   TRUE if the external link exists, FALSE otherwise.
261
 *
262
 * @see ext_links_load()
263
 */
264
function ext_links_exists($ext_link_name) {
265
  return (bool) db_query_range('SELECT 1 FROM {ext_links} WHERE id = :id', 0, 1, array(':id' => $ext_link_name))->fetchField();
266
}
267

    
268
/**
269
 * Autocomplete function called via the menu hook ext_links/category/autocomplete
270
 *
271
 * @param $query_string
272
 *  the string to search for
273
 */
274
function ext_links_category_autocomplete($query_string){
275
  $matches = array();
276
  $sql = 'SELECT * FROM {ext_links} WHERE category LIKE :category';
277
  $args = [':category' => '%' . db_like($query_string) . '%'];
278
  $result = db_query($sql, $args);
279
  foreach ($result as $row) {
280
    $matches[$row->category] = check_plain($row->category);
281
  }
282
  // Return the result to the form in json
283
  drupal_json_output($matches);
284
}
285

    
286
/**
287
 * Returns the genus and the first epithet from the object taxon.
288
 *
289
 * @param $taxon
290
 *   A CDM Taxon instance object
291
 * @return array
292
 *  An associate array with two elements:
293
 *     - genus: the uninomial
294
 *     - species: the species epithet
295
 */
296
function ext_link_species_name($taxon) {
297
  $speciesName = array();
298
  $i = 0;
299
  while (isset($taxon->name->taggedName[$i]) && !isset($speciesName['species'])) {
300
    if ($taxon->name->taggedName[$i]->type == "name") {
301
      if (!isset($speciesName['genus'])) {
302
        $speciesName['genus'] = $taxon->name->taggedName[$i]->text;
303
      }
304
      else {
305
        $speciesName['species'] = $taxon->name->taggedName[$i]->text;
306
      }
307
    }
308
    $i++;
309
  }
310
  return $speciesName;
311
}
312

    
313
/**
314
 * Implements hook_block_info().
315
 */
316
function ext_links_block_info() {
317
  if (TRUE) {
318
    $block[0]["info"] = t("CDM - External Links");
319
    $block[0]["visibility"] = BLOCK_VISIBILITY_LISTED;
320
    $block[0]["pages"] = "cdm_dataportal/taxon/*\ncdm_dataportal/name/*";
321
    return $block;
322
  }
323
}
324

    
325
/**
326
 * Implements hook_block_view().
327
 */
328
function ext_links_block_view($delta) {
329
  switch ($delta) {
330
    case '0':
331
      $block['subject'] = t('Search name in') . ' ...';
332
      drupal_add_js(drupal_get_path('module', 'ext_links') . '/ext_links.js');
333
      if (variable_get('ext_links_appearance_grouped', 1)) {
334
        $block['content'] = render_ext_links_list_grouped();
335
      } else {
336
        $block['content'] = render_ext_links_list_plain();
337
      }
338
    }
339
      return $block;
340
}
341

    
342
/**
343
 * Applies the name tokens to the external link templates.
344
 *
345
 * @param $ext_link_template
346
 *
347
 * @return array
348
 *  Array with the keys:
349
 *     - title: the title of the link
350
 *     - url: the url of the link
351
 */
352
function ext_links_apply_template($ext_link_template) {
353
      $ext_link_array = [
354
        'title' => $ext_link_template->title,
355
        'url' => token_replace($ext_link_template->link, [],
356
          [
357
            'callback' => 'ext_links_token_replacement_urlencode',
358
            'clear' => true
359
          ])
360
      ];
361
  return $ext_link_array;
362
}
363

    
364
/**
365
 * Callback function to be passed to token_replace() to urlencode the token replacements.
366
 *
367
 * @param array $replacements
368
 *   The replacements for the tokens
369
 * @param array $data
370
 *    Unused, see token_replace()
371
 * @param array $options
372
 *    Unused, see token_replace()
373
 *
374
 * @see token_replace()
375
 */
376
function ext_links_token_replacement_urlencode(array &$replacements, array $data = [], array $options = []){
377
  foreach ($replacements as &$repl){
378
    $repl = rawurlencode($repl);
379
  }
380

    
381
}
382

    
383
/**
384
 * Creates html markup of ext_links grouped by category
385
 */
386
function render_ext_links_list_grouped() {
387

    
388
  $ext_links = ext_links_templates(true);
389

    
390
  $ext_links_by_category = [];
391

    
392
  foreach ($ext_links as $ext_link) {
393
    if(!array_key_exists($ext_link->category, $ext_links_by_category)){
394
      $ext_links_by_category[$ext_link->category] = [];
395
    }
396
    $ext_link_render_array = ext_links_apply_template($ext_link);
397
    $ext_links_by_category[$ext_link->category][] = $ext_link_render_array;
398
  }
399

    
400
  $block_content = '';
401
  foreach ($ext_links_by_category as $category => $ext_links) {
402
    $block_content .= "<label class=\"category-label\">" . $category . "</label><div class=\"category category-$category\">";
403
    foreach($ext_links as $ext_link){
404
      $block_content .= l($ext_link['title'], 'JavaScript:popupExternalLinks(\'' . $ext_link['url'] . '\')', ['external' => TRUE]) .'<br />';
405
    }
406
    $block_content .= "</div>";
407
  }
408

    
409
  return $block_content;
410
}
411

    
412
/**
413
 * Creates html markup of ext_links as plain list
414
 */
415
function render_ext_links_list_plain() {
416

    
417
  $ext_links_templates = ext_links_templates(true);
418
  $block_content = '';
419
  foreach ($ext_links_templates as $ext_link) {
420
    $ext_link = ext_links_apply_template($ext_link);
421
    $block_content .= l($ext_link['title'], 'JavaScript:popupExternalLinks(\'' . $ext_link['url'] . '\')', ['external' => TRUE]) .'<br />';
422
  }
423
  return $block_content;
424
}
425

    
426
/**
427
 * Implements hook_theme()
428
 */
429
function ext_links_theme() {
430
  return array(
431
    // theme_ext_links_admin_overview
432
    'ext_links_admin_overview' => array(
433
      'render element' => 'form',
434
      'file' => 'ext_links.admin.inc',
435
    )
436
  );
437
}
438

    
439
/**
440
 * Get the default external links.
441
 *
442
 * @return array
443
 *   Returns an array with default external links values.
444
 */
445
function ext_links_template_defaults() {
446

    
447
  // --- General ---
448
  $ext_links_default["eol"] = array(
449
    'id' => "eol",
450
    'link' => 'http://eol.org/search/?q=[cdm:taxon_name]',
451
    'title' => 'Encyclopaedia of Life',
452
    'weight' => 0,
453
    'status' => 1,
454
    'category' => 'General',
455
  );
456
  $ext_links_default["jstor"] = array(
457
    'id' => "jstor",
458
    'link' => 'https://plants.jstor.org/search?filter=name&so=ps_group_by_genus_species+asc&Query=[cdm:taxon_name]',
459
    'title' => 'JSTOR Plant Science',
460
    'weight' => 0,
461
    'status' => 1,
462
    'category' => 'General',
463
  );
464

    
465
  // --- Classification/Nomenclature ---
466
  $ext_links_default["col"] = array(
467
    'id' => "col",
468
    'link' => 'https://www.catalogueoflife.org/data/search?facet=rank&facet=issue&facet=status&facet=nomStatus&facet=nameType&facet=field&limit=50&offset=0&q=[cdm:taxon_name]&sortBy=taxonomic&type=EXACT',
469
    'title' => 'Catalogue of Life',
470
    'weight' => 0,
471
    'status' => 1,
472
    'category' => 'Classification/Nomenclature',
473
  );
474
  $ext_links_default["ipni"] = array(
475
    'id' => "ipni",
476
    'link' => 'https://www.ipni.org/?q=[cdm:taxon_name]',
477
    'title' => 'IPNI',
478
    'weight' => 0,
479
    'status' => 1,
480
    'category' => 'Classification/Nomenclature',
481
  );
482
  $ext_links_default["tpl"] = array(
483
    'id' => "tpl",
484
    'link' => 'http://www.theplantlist.org/tpl/search?q=[cdm:taxon_name]',
485
    'title' => 'The Plant List',
486
    'weight' => 0,
487
    'status' => 1,
488
    'category' => 'Classification/Nomenclature',
489
  );
490
  $ext_links_default["wcsp"] = array(
491
    'id' => "wcsp",
492
    'link' => 'http://wcsp.science.kew.org/qsearch.do?plantName=[cdm:taxon_name]',
493
    'title' => 'World Checklist Monocots',
494
    'weight' => 0,
495
    'status' => 1,
496
    'category' => 'Classification/Nomenclature',
497
  );
498
  $ext_links_default["wfo"] = array(
499
    'id' => "wfo",
500
    'link' => 'http://www.worldfloraonline.org/search?query=[cdm:taxon_name]',
501
    'title' => 'World Flora Online',
502
    'weight' => 0,
503
    'status' => 1,
504
    'category' => 'Classification/Nomenclature',
505
  );
506

    
507
  // --- Specimens/Occurrences ---
508
  $ext_links_default["biocase"] = array(
509
    'id' => "biocase",
510
    'link' => 'http://search.biocase.org/edit/search/units/simpleSearch/query1?unitName=[cdm:taxon_name]',
511
    'title' => 'BioCASE',
512
    'weight' => 0,
513
    'status' => 1,
514
    'category' => 'Specimens/Occurrences',
515
  );
516
  $ext_links_default["fairchild"] = array(
517
    //disabled since Fairchild Guide To Palms seems to be down
518
    'id' => "fairchild",
519
    'link' => 'http://palmguide.org/palmsearch.php?query=',
520
    'title' => 'Fairchild Guide To Palms',
521
    'weight' => 0,
522
    'status' => 0,
523
    'category' => 'Specimens/Occurrences',
524
  );
525
  $ext_links_default["gbif"] = array(
526
    'id' => "gbif",
527
    'link' => 'http://www.gbif.org/species/search?q=[cdm:taxon_name]',
528
    'title' => 'GBIF',
529
    'weight' => 0,
530
    'status' => 1,
531
    'category' => 'Specimens/Occurrences',
532
  );
533
  $ext_links_default["herbcat"] = array(
534
    'id' => "herbcat",
535
    'link' => 'http://apps.kew.org/herbcat/getSearchPageResults.do?typeSpecimen=false&imageSpecimen=false&currentName=false&typeOfCollection=all_collection&&genus=[cdm:taxon_name:genus_or_uninomial]&&species=[cdm:taxon_name:epithet]&infraspecificName=[cdm:taxon_name:infraspecific_epithet]',
536
    'title' => 'Kew Herbarium Catalogue',
537
    'weight' => 0,
538
    'status' => 1,
539
    'category' => 'Specimens/Occurrences',
540
  );
541
  $ext_links_default["nybg"] = array(
542
    'id' => "nybg",
543
    'link' => 'http://sweetgum.nybg.org/science/vh/specimen_list.php?SummaryData=[cdm:taxon_name]',
544
    'title' => 'NYBG',
545
    'weight' => 0,
546
    'status' => 1,
547
    'category' => 'Specimens/Occurrences',
548
  );
549
  $ext_links_default["tropicos"] = array(
550
    'id' => "tropicos",
551
    'link' => 'http://www.tropicos.org/NameSearch.aspx?name=[cdm:taxon_name]',
552
    'title' => 'Tropicos',
553
    'weight' => 0,
554
    'status' => 1,
555
    'category' => 'Specimens/Occurrences',
556
  );
557
  $ext_links_default["wfo-specimens"] = array(
558
    'id' => "wfo-specimens",
559
    'link' => 'http://wfospecimens.cybertaxonomy.org/search/result?fullScientificName=[cdm:taxon_name]',
560
    'title' => 'World Flora Online - Specimens',
561
    'weight' => 0,
562
    'status' => 1,
563
    'category' => 'Specimens/Occurrences',
564
  );
565

    
566
  // --- Molecular Resources ---
567
  $ext_links_default["ggbn"] = array(
568
    'id' => "ggbn",
569
    'link' => 'http://www.ggbn.org/ggbn_portal/search/result?fullScientificName=[cdm:taxon_name]',
570
    'title' => 'GGBN',
571
    'weight' => 0,
572
    'status' => 1,
573
    'category' => 'Molecular Resources',
574
  );
575
  $ext_links_default["ncbi"] = array(
576
    'id' => "ncbi",
577
    'link' => 'http://www.ncbi.nlm.nih.gov/gquery/gquery.fcgi?term=%22[cdm:taxon_name]%22',
578
    'title' => 'NCBI',
579
    'weight' => 0,
580
    'status' => 1,
581
    'category' => 'Molecular Resources',
582
  );
583

    
584
  // --- Images ---
585
  $ext_links_default["europeana"] = array(
586
    'id' => "europeana",
587
    'link' => 'https://www.europeana.eu/en/search?query=[cdm:taxon_name]',
588
    'title' => 'Europeana',
589
    'weight' => 0,
590
    'status' => 1,
591
    'category' => 'Images',
592
  );
593
  $ext_links_default["flickr"] = array(
594
    'id' => "flickr",
595
    'link' => 'http://www.flickr.com/search/?w=all&q=%22[cdm:taxon_name]%22',
596
    'title' => 'flickr',
597
    'weight' => 0,
598
    'status' => 1,
599
    'category' => 'Images',
600
  );
601
  $ext_links_default["google"] = array(
602
    'id' => "google",
603
    'link' => 'http://images.google.com/images?q=%22[cdm:taxon_name]%22',
604
    'title' => 'Google Images',
605
    'weight' => 0,
606
    'status' => 1,
607
    'category' => 'Images',
608
  );
609
  $ext_links_default["morphbank"] = array(
610
    'id' => "morphbank",
611
    'link' => 'https://www.morphbank.net/Browse/ByImage/index.php?keywords=&tsnKeywords=[cdm:taxon_name]',
612
    'title' => 'Morphbank',
613
    'weight' => 0,
614
    'status' => 1,
615
    'category' => 'Images',
616
  );
617

    
618
  // --- Conservation ---
619
  $ext_links_default["iucn"] = array(
620
    'id' => "iucn",
621
    'link' => 'https://www.iucnredlist.org/search?query=[cdm:taxon_name]',
622
    'title' => 'IUCN Red List',
623
    'weight' => 0,
624
    'status' => 1,
625
    'category' => 'Conservation',
626
  );
627

    
628
  // --- Literature ---
629
  $ext_links_default["scholar"] = array(
630
    'id' => "scholar",
631
    'link' => 'http://scholar.google.de/scholar?q=%22[cdm:taxon_name]%22',
632
    'title' => 'Google scholar',
633
    'weight' => 0,
634
    'status' => 1,
635
    'category' => 'Literature',
636
  );
637
  $ext_links_default["bhl"] = array(
638
    'id' => "bhl",
639
    // BHL does not normalize rank terms, ssp., sub., subsp. are not unified, therefore we skip that part:
640
    'link' => 'https://www.biodiversitylibrary.org/search?searchTerm=[cdm:taxon_name:genus_or_uninomial]+[cdm:taxon_name:epithet]+[cdm:taxon_name:infraspecific_epithet]&stype=F#/names',
641
    'title' => 'BHL',
642
    'weight' => 0,
643
    'status' => 1,
644
    'category' => 'Literature',
645
  );
646
  $ext_links_default["pubmed"] = array(
647
    'id' => "pubmed",
648
    'link' => 'https://pubmed.ncbi.nlm.nih.gov/?term=[cdm:taxon_name]',
649
    'title' => 'PubMed',
650
    'weight' => 0,
651
    'status' => 1,
652
    'category' => 'Literature',
653
  );
654

    
655
  $weight = -10;
656
  foreach($ext_links_default as &$template){
657
    $template['weight'] = $weight++;
658
  }
659

    
660
  return $ext_links_default;
661
}
(6-6/6)