get_attachment_template

The timeline below displays how wordpress function get_attachment_template has changed across different WordPress versions. If a version is not listed, refer to the next available version below.

WordPress Version: 6.5

/**
 * Retrieves path of attachment template in current or parent template.
 *
 * The hierarchy for this template looks like:
 *
 * 1. {mime_type}-{sub_type}.php
 * 2. {sub_type}.php
 * 3. {mime_type}.php
 * 4. attachment.php
 *
 * An example of this is:
 *
 * 1. image-jpeg.php
 * 2. jpeg.php
 * 3. image.php
 * 4. attachment.php
 *
 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'}
 * and {@see '$type_template'} dynamic hooks, where `$type` is 'attachment'.
 *
 * @since 2.0.0
 * @since 4.3.0 The order of the mime type logic was reversed so the hierarchy is more logical.
 *
 * @see get_query_template()
 *
 * @return string Full path to attachment template file.
 */
function get_attachment_template()
{
    $attachment = get_queried_object();
    $templates = array();
    if ($attachment) {
        if (str_contains($attachment->post_mime_type, '/')) {
            list($type, $subtype) = explode('/', $attachment->post_mime_type);
        } else {
            list($type, $subtype) = array($attachment->post_mime_type, '');
        }
        if (!empty($subtype)) {
            $templates[] = "{$type}-{$subtype}.php";
            $templates[] = "{$subtype}.php";
        }
        $templates[] = "{$type}.php";
    }
    $templates[] = 'attachment.php';
    return get_query_template('attachment', $templates);
}

WordPress Version: 6.3

/**
 * Retrieves path of attachment template in current or parent template.
 *
 * The hierarchy for this template looks like:
 *
 * 1. {mime_type}-{sub_type}.php
 * 2. {sub_type}.php
 * 3. {mime_type}.php
 * 4. attachment.php
 *
 * An example of this is:
 *
 * 1. image-jpeg.php
 * 2. jpeg.php
 * 3. image.php
 * 4. attachment.php
 *
 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'}
 * and {@see '$type_template'} dynamic hooks, where `$type` is 'attachment'.
 *
 * @since 2.0.0
 * @since 4.3.0 The order of the mime type logic was reversed so the hierarchy is more logical.
 *
 * @see get_query_template()
 *
 * @global array $posts
 *
 * @return string Full path to attachment template file.
 */
function get_attachment_template()
{
    $attachment = get_queried_object();
    $templates = array();
    if ($attachment) {
        if (str_contains($attachment->post_mime_type, '/')) {
            list($type, $subtype) = explode('/', $attachment->post_mime_type);
        } else {
            list($type, $subtype) = array($attachment->post_mime_type, '');
        }
        if (!empty($subtype)) {
            $templates[] = "{$type}-{$subtype}.php";
            $templates[] = "{$subtype}.php";
        }
        $templates[] = "{$type}.php";
    }
    $templates[] = 'attachment.php';
    return get_query_template('attachment', $templates);
}

WordPress Version: 6.1

/**
 * Retrieves path of attachment template in current or parent template.
 *
 * The hierarchy for this template looks like:
 *
 * 1. {mime_type}-{sub_type}.php
 * 2. {sub_type}.php
 * 3. {mime_type}.php
 * 4. attachment.php
 *
 * An example of this is:
 *
 * 1. image-jpeg.php
 * 2. jpeg.php
 * 3. image.php
 * 4. attachment.php
 *
 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'}
 * and {@see '$type_template'} dynamic hooks, where `$type` is 'attachment'.
 *
 * @since 2.0.0
 * @since 4.3.0 The order of the mime type logic was reversed so the hierarchy is more logical.
 *
 * @see get_query_template()
 *
 * @global array $posts
 *
 * @return string Full path to attachment template file.
 */
function get_attachment_template()
{
    $attachment = get_queried_object();
    $templates = array();
    if ($attachment) {
        if (false !== strpos($attachment->post_mime_type, '/')) {
            list($type, $subtype) = explode('/', $attachment->post_mime_type);
        } else {
            list($type, $subtype) = array($attachment->post_mime_type, '');
        }
        if (!empty($subtype)) {
            $templates[] = "{$type}-{$subtype}.php";
            $templates[] = "{$subtype}.php";
        }
        $templates[] = "{$type}.php";
    }
    $templates[] = 'attachment.php';
    return get_query_template('attachment', $templates);
}

WordPress Version: 4.9

/**
 * Retrieve path of attachment template in current or parent template.
 *
 * The hierarchy for this template looks like:
 *
 * 1. {mime_type}-{sub_type}.php
 * 2. {sub_type}.php
 * 3. {mime_type}.php
 * 4. attachment.php
 *
 * An example of this is:
 *
 * 1. image-jpeg.php
 * 2. jpeg.php
 * 3. image.php
 * 4. attachment.php
 *
 * The template hierarchy and template path are filterable via the {@see '$type_template_hierarchy'}
 * and {@see '$type_template'} dynamic hooks, where `$type` is 'attachment'.
 *
 * @since 2.0.0
 * @since 4.3.0 The order of the mime type logic was reversed so the hierarchy is more logical.
 *
 * @see get_query_template()
 *
 * @global array $posts
 *
 * @return string Full path to attachment template file.
 */
function get_attachment_template()
{
    $attachment = get_queried_object();
    $templates = array();
    if ($attachment) {
        if (false !== strpos($attachment->post_mime_type, '/')) {
            list($type, $subtype) = explode('/', $attachment->post_mime_type);
        } else {
            list($type, $subtype) = array($attachment->post_mime_type, '');
        }
        if (!empty($subtype)) {
            $templates[] = "{$type}-{$subtype}.php";
            $templates[] = "{$subtype}.php";
        }
        $templates[] = "{$type}.php";
    }
    $templates[] = 'attachment.php';
    return get_query_template('attachment', $templates);
}

WordPress Version: 4.7

/**
 * Retrieve path of attachment template in current or parent template.
 *
 * The hierarchy for this template looks like:
 *
 * 1. {mime_type}-{sub_type}.php
 * 2. {sub_type}.php
 * 3. {mime_type}.php
 * 4. attachment.php
 *
 * An example of this is:
 *
 * 1. image-jpeg.php
 * 2. jpeg.php
 * 3. image.php
 * 4. attachment.php
 *
 * The template hierarchy is filterable via the {@see 'attachment_template_hierarchy'} hook.
 * The template path is filterable via the {@see 'attachment_template'} hook.
 *
 * @since 2.0.0
 * @since 4.3.0 The order of the mime type logic was reversed so the hierarchy is more logical.
 *
 * @see get_query_template()
 *
 * @global array $posts
 *
 * @return string Full path to attachment template file.
 */
function get_attachment_template()
{
    $attachment = get_queried_object();
    $templates = array();
    if ($attachment) {
        if (false !== strpos($attachment->post_mime_type, '/')) {
            list($type, $subtype) = explode('/', $attachment->post_mime_type);
        } else {
            list($type, $subtype) = array($attachment->post_mime_type, '');
        }
        if (!empty($subtype)) {
            $templates[] = "{$type}-{$subtype}.php";
            $templates[] = "{$subtype}.php";
        }
        $templates[] = "{$type}.php";
    }
    $templates[] = 'attachment.php';
    return get_query_template('attachment', $templates);
}

WordPress Version: 4.3

/**
 * Retrieve path of attachment template in current or parent template.
 *
 * The attachment path first checks if the first part of the mime type exists.
 * The second check is for the second part of the mime type. The last check is
 * for both types separated by an underscore. If neither are found then the file
 * 'attachment.php' is checked and returned.
 *
 * Some examples for the 'text/plain' mime type are 'text.php', 'plain.php', and
 * finally 'text-plain.php'.
 *
 * The template path is filterable via the dynamic {@see '$type_template'} hook,
 * e.g. 'attachment_template'.
 *
 * @since 2.0.0
 *
 * @see get_query_template()
 *
 * @global array $posts
 *
 * @return string Full path to attachment template file.
 */
function get_attachment_template()
{
    $attachment = get_queried_object();
    $templates = array();
    if ($attachment) {
        if (false !== strpos($attachment->post_mime_type, '/')) {
            list($type, $subtype) = explode('/', $attachment->post_mime_type);
        } else {
            list($type, $subtype) = array($attachment->post_mime_type, '');
        }
        if (!empty($subtype)) {
            $templates[] = "{$type}-{$subtype}.php";
            $templates[] = "{$subtype}.php";
        }
        $templates[] = "{$type}.php";
    }
    $templates[] = 'attachment.php';
    return get_query_template('attachment', $templates);
}

WordPress Version: 3.9

/**
 * Retrieve path of attachment template in current or parent template.
 *
 * The attachment path first checks if the first part of the mime type exists.
 * The second check is for the second part of the mime type. The last check is
 * for both types separated by an underscore. If neither are found then the file
 * 'attachment.php' is checked and returned.
 *
 * Some examples for the 'text/plain' mime type are 'text.php', 'plain.php', and
 * finally 'text_plain.php'.
 *
 * The template path is filterable via the 'attachment_template' hook.
 *
 * @since 2.0.0
 *
 * @see get_query_template()
 *
 * @return string Full path to attachment template file.
 */
function get_attachment_template()
{
    global $posts;
    if (!empty($posts) && isset($posts[0]->post_mime_type)) {
        $type = explode('/', $posts[0]->post_mime_type);
        if (!empty($type)) {
            if ($template = get_query_template($type[0])) {
                return $template;
            } elseif (!empty($type[1])) {
                if ($template = get_query_template($type[1])) {
                    return $template;
                } elseif ($template = get_query_template("{$type[0]}_{$type[1]}")) {
                    return $template;
                }
            }
        }
    }
    return get_query_template('attachment');
}

WordPress Version: 3.7

/**
 * Retrieve path of attachment template in current or parent template.
 *
 * The attachment path first checks if the first part of the mime type exists.
 * The second check is for the second part of the mime type. The last check is
 * for both types separated by an underscore. If neither are found then the file
 * 'attachment.php' is checked and returned.
 *
 * Some examples for the 'text/plain' mime type are 'text.php', 'plain.php', and
 * finally 'text_plain.php'.
 *
 * @since 2.0.0
 *
 * @return string
 */
function get_attachment_template()
{
    global $posts;
    if (!empty($posts) && isset($posts[0]->post_mime_type)) {
        $type = explode('/', $posts[0]->post_mime_type);
        if (!empty($type)) {
            if ($template = get_query_template($type[0])) {
                return $template;
            } elseif (!empty($type[1])) {
                if ($template = get_query_template($type[1])) {
                    return $template;
                } elseif ($template = get_query_template("{$type[0]}_{$type[1]}")) {
                    return $template;
                }
            }
        }
    }
    return get_query_template('attachment');
}