taxonomy.pages.inc

Page callbacks for the taxonomy module.

File

modules/taxonomy/taxonomy.pages.inc

View source
<?php


/**
 * @file
 * Page callbacks for the taxonomy module.
 */

/**
 * Menu callback; displays all nodes associated with a term.
 *
 * @param $term
 *   The taxonomy term.
 * @return
 *   The page content.
 */
function taxonomy_term_page($term) {
    // If there is a menu link to this term, the link becomes the last part of
    // the active trail, and the link name becomes the page title. Thus, we must
    // explicitly set the page title to be the term title.
    drupal_set_title($term->name);
    // Build breadcrumb based on the hierarchy of the term.
    $current = (object) array(
        'tid' => $term->tid,
    );
    // @todo This overrides any other possible breadcrumb and is a pure hard-coded
    //   presumption. Make this behavior configurable per vocabulary or term.
    $breadcrumb = array();
    while ($parents = taxonomy_get_parents($current->tid)) {
        $current = array_shift($parents);
        $breadcrumb[] = l($current->name, 'taxonomy/term/' . $current->tid);
    }
    $breadcrumb[] = l(t('Home'), NULL);
    $breadcrumb = array_reverse($breadcrumb);
    drupal_set_breadcrumb($breadcrumb);
    drupal_add_feed('taxonomy/term/' . $term->tid . '/feed', 'RSS - ' . $term->name);
    // Set the term path as the canonical URL to prevent duplicate content.
    $uri = entity_uri('taxonomy_term', $term);
    drupal_add_html_head_link(array(
        'rel' => 'canonical',
        'href' => url($uri['path'], $uri['options']),
    ), TRUE);
    // Set the non-aliased path as a default shortlink.
    drupal_add_html_head_link(array(
        'rel' => 'shortlink',
        'href' => url($uri['path'], array_merge($uri['options'], array(
            'alias' => TRUE,
        ))),
    ), TRUE);
    // Normally we would call taxonomy_term_show() here, but for backwards
    // compatibility in Drupal 7 we do not want to do that (it produces different
    // data structures and HTML markup than what Drupal 7 released with). Calling
    // taxonomy_term_view() directly provides essentially the same thing, but
    // allows us to wrap the rendered term in our desired array structure.
    $build['term_heading'] = array(
        '#prefix' => '<div class="term-listing-heading">',
        '#suffix' => '</div>',
        'term' => taxonomy_term_view($term, 'full'),
    );
    if ($nids = taxonomy_select_nodes($term->tid, TRUE, variable_get('default_nodes_main', 10))) {
        $nodes = node_load_multiple($nids);
        $build += node_view_multiple($nodes);
        $build['pager'] = array(
            '#theme' => 'pager',
            '#weight' => 5,
        );
    }
    else {
        $build['no_content'] = array(
            '#prefix' => '<p>',
            '#markup' => t('There is currently no content classified with this term.'),
            '#suffix' => '</p>',
        );
    }
    return $build;
}

/**
 * Generate the content feed for a taxonomy term.
 *
 * @param $term
 *   The taxonomy term.
 */
function taxonomy_term_feed($term) {
    $channel['link'] = url('taxonomy/term/' . $term->tid, array(
        'absolute' => TRUE,
    ));
    $channel['title'] = variable_get('site_name', 'Drupal') . ' - ' . $term->name;
    // Only display the description if we have a single term, to avoid clutter and confusion.
    // HTML will be removed from feed description.
    $channel['description'] = check_markup($term->description, $term->format, '', TRUE);
    $nids = taxonomy_select_nodes($term->tid, FALSE, variable_get('feed_default_items', 10));
    node_feed($nids, $channel);
}

/**
 * Page callback: Outputs JSON for taxonomy autocomplete suggestions.
 *
 * Path: taxonomy/autocomplete
 *
 * This callback outputs term name suggestions in response to Ajax requests
 * made by the taxonomy autocomplete widget for taxonomy term reference
 * fields. The output is a JSON object of plain-text term suggestions, keyed by
 * the user-entered value with the completed term name appended.  Term names
 * containing commas are wrapped in quotes.
 *
 * For example, suppose the user has entered the string 'red fish, blue' in the
 * field, and there are two taxonomy terms, 'blue fish' and 'blue moon'. The
 * JSON output would have the following structure:
 * @code
 *   {
 *     "red fish, blue fish": "blue fish",
 *     "red fish, blue moon": "blue moon",
 *   };
 * @endcode
 *
 * @param $field_name
 *   The name of the term reference field.
 * @param $tags_typed
 *   (optional) A comma-separated list of term names entered in the
 *   autocomplete form element. Only the last term is used for autocompletion.
 *   Defaults to '' (an empty string).
 *
 * @see taxonomy_menu()
 * @see taxonomy_field_widget_info()
 */
function taxonomy_autocomplete($field_name = '', $tags_typed = '') {
    // If the request has a '/' in the search text, then the menu system will have
    // split it into multiple arguments, recover the intended $tags_typed.
    $args = func_get_args();
    // Shift off the $field_name argument.
    array_shift($args);
    $tags_typed = implode('/', $args);
    // Make sure the field exists and is a taxonomy field.
    if (!($field = field_info_field($field_name)) || $field['type'] !== 'taxonomy_term_reference') {
        // Error string. The JavaScript handler will realize this is not JSON and
        // will display it as debugging information.
        print t('Taxonomy field @field_name not found.', array(
            '@field_name' => $field_name,
        ));
        exit;
    }
    // The user enters a comma-separated list of tags. We only autocomplete the last tag.
    $tags_typed = drupal_explode_tags($tags_typed);
    $tag_last = drupal_strtolower(array_pop($tags_typed));
    $term_matches = array();
    if ($tag_last != '') {
        // Part of the criteria for the query come from the field's own settings.
        $vids = array();
        $vocabularies = taxonomy_vocabulary_get_names();
        foreach ($field['settings']['allowed_values'] as $tree) {
            $vids[] = $vocabularies[$tree['vocabulary']]->vid;
        }
        $query = db_select('taxonomy_term_data', 't');
        $query->addTag('translatable');
        $query->addTag('taxonomy_term_access');
        // Do not select already entered terms.
        if (!empty($tags_typed)) {
            $query->condition('t.name', $tags_typed, 'NOT IN');
        }
        // Select rows that match by term name.
        $tags_return = $query->fields('t', array(
            'tid',
            'name',
        ))
            ->condition('t.vid', $vids)
            ->condition('t.name', '%' . db_like($tag_last) . '%', 'LIKE')
            ->range(0, 10)
            ->execute()
            ->fetchAllKeyed();
        $prefix = count($tags_typed) ? drupal_implode_tags($tags_typed) . ', ' : '';
        foreach ($tags_return as $tid => $name) {
            $n = $name;
            // Term names containing commas or quotes must be wrapped in quotes.
            if (strpos($name, ',') !== FALSE || strpos($name, '"') !== FALSE) {
                $n = '"' . str_replace('"', '""', $name) . '"';
            }
            $term_matches[$prefix . $n] = check_plain($name);
        }
    }
    drupal_json_output($term_matches);
}

Functions

Title Deprecated Summary
taxonomy_autocomplete Page callback: Outputs JSON for taxonomy autocomplete suggestions.
taxonomy_term_feed Generate the content feed for a taxonomy term.
taxonomy_term_page Menu callback; displays all nodes associated with a term.

Buggy or inaccurate documentation? Please file an issue. Need support? Need help programming? Connect with the Drupal community.