wp_playlist_shortcode()
概述
wp_playlist_shortcode() 是 WordPress 中用于生成播放列表短码输出的核心函数,支持音频和视频文件的集合展示。它处理短码属性、查询附件数据,并生成相应的 HTML 和 JavaScript 输出。
关键要点
- 函数实现播放列表短码功能,用于在文章中显示 WordPress 音频或视频文件集合。
- 接受多种参数,如 type(类型,默认为 'audio')、order(排序)、ids(附件 ID 数组)、style(样式,默认为 'light')等,以自定义播放列表行为。
- 内部使用 shortcode_atts() 合并默认属性,并通过 WP_Query 相关函数(如 get_posts() 或 get_children())获取附件数据。
- 支持过滤器 post_playlist 以允许自定义输出,以及动作 wp_playlist_scripts 来加载脚本和样式。
- 返回播放列表的 HTML 字符串,如果类型不支持或附件为空则返回空字符串。
代码示例
function wp_playlist_shortcode( $attr ) {
global $content_width;
$post = get_post();
static $instance = 0;
++$instance;
static $is_loaded = false;
if ( ! empty( $attr['ids'] ) ) {
if ( empty( $attr['orderby'] ) ) {
$attr['orderby'] = 'post__in';
}
$attr['include'] = $attr['ids'];
}
$output = apply_filters( 'post_playlist', '', $attr, $instance );
if ( ! empty( $output ) ) {
return $output;
}
$atts = shortcode_atts(
array(
'type' => 'audio',
'order' => 'ASC',
'orderby' => 'menu_order ID',
'id' => $post ? $post->ID : 0,
'include' => '',
'exclude' => '',
'style' => 'light',
'tracklist' => true,
'tracknumbers' => true,
'images' => true,
'artists' => true,
),
$attr,
'playlist'
);
// 后续处理逻辑...
}注意事项
- 当传递 ids 参数时,orderby 默认设置为 'post__in' 以保持 ID 顺序;否则默认为 'menu_order ID'。
- 如果用户无法读取文章或文章受密码保护,函数会提前返回空字符串。
- 在 Feed 中,输出简化为附件链接列表,而非完整播放列表界面。
- 视频播放列表会根据附件元数据动态计算尺寸,以适应主题内容宽度。
Builds the Playlist shortcode output.
Description
This implements the functionality of the playlist shortcode for displaying a collection of WordPress audio or video files in a post.
Parameters
$attrarrayrequired-
Array of default playlist attributes.
typestringType of playlist to display. Accepts'audio'or'video'. Default'audio'.orderstringDesignates ascending or descending order of items in the playlist.
Accepts'ASC','DESC'. Default'ASC'.orderbystringAny column, or columns, to sort the playlist. If $ids are passed, this defaults to the order of the $ids array ('post__in').
Otherwise default is ‘menu_order ID’.idintIf an explicit $ids array is not present, this parameter will determine which attachments are used for the playlist.
Default is the current post ID.idsarrayCreate a playlist out of these explicit attachment IDs. If empty, a playlist will be created from all $type attachments of $id.
Default empty.excludearrayList of specific attachment IDs to exclude from the playlist. Default empty.stylestringPlaylist style to use. Accepts'light'or'dark'. Default'light'.tracklistboolWhether to show or hide the playlist. Default true.tracknumbersboolWhether to show or hide the numbers next to entries in the playlist. Default true.imagesboolShow or hide the video or audio thumbnail (Featured Image/post thumbnail). Default true.artistsboolWhether to show or hide artist name in the playlist. Default true.
Source
function wp_playlist_shortcode( $attr ) {
global $content_width;
$post = get_post();
static $instance = 0;
++$instance;
static $is_loaded = false;
if ( ! empty( $attr['ids'] ) ) {
// 'ids' is explicitly ordered, unless you specify otherwise.
if ( empty( $attr['orderby'] ) ) {
$attr['orderby'] = 'post__in';
}
$attr['include'] = $attr['ids'];
}
/**
* Filters the playlist output.
*
* Returning a non-empty value from the filter will short-circuit generation
* of the default playlist output, returning the passed value instead.
*
* @since 3.9.0
* @since 4.2.0 The `$instance` parameter was added.
*
* @param string $output Playlist output. Default empty.
* @param array $attr An array of shortcode attributes.
* @param int $instance Unique numeric ID of this playlist shortcode instance.
*/
$output = apply_filters( 'post_playlist', '', $attr, $instance );
if ( ! empty( $output ) ) {
return $output;
}
$atts = shortcode_atts(
array(
'type' => 'audio',
'order' => 'ASC',
'orderby' => 'menu_order ID',
'id' => $post ? $post->ID : 0,
'include' => '',
'exclude' => '',
'style' => 'light',
'tracklist' => true,
'tracknumbers' => true,
'images' => true,
'artists' => true,
),
$attr,
'playlist'
);
$id = (int) $atts['id'];
if ( 'audio' !== $atts['type'] ) {
$atts['type'] = 'video';
}
$args = array(
'post_status' => 'inherit',
'post_type' => 'attachment',
'post_mime_type' => $atts['type'],
'order' => $atts['order'],
'orderby' => $atts['orderby'],
);
if ( ! empty( $atts['include'] ) ) {
$args['include'] = $atts['include'];
$_attachments = get_posts( $args );
$attachments = array();
foreach ( $_attachments as $key => $val ) {
$attachments[ $val->ID ] = $_attachments[ $key ];
}
} elseif ( ! empty( $atts['exclude'] ) ) {
$args['post_parent'] = $id;
$args['exclude'] = $atts['exclude'];
$attachments = get_children( $args );
} else {
$args['post_parent'] = $id;
$attachments = get_children( $args );
}
if ( ! empty( $args['post_parent'] ) ) {
$post_parent = get_post( $id );
// Terminate the shortcode execution if the user cannot read the post or it is password-protected.
if ( ! current_user_can( 'read_post', $post_parent->ID ) || post_password_required( $post_parent ) ) {
return '';
}
}
if ( empty( $attachments ) ) {
return '';
}
if ( is_feed() ) {
$output = "n";
foreach ( $attachments as $att_id => $attachment ) {
$output .= wp_get_attachment_link( $att_id ) . "n";
}
return $output;
}
$outer = 22; // Default padding and border of wrapper.
$default_width = 640;
$default_height = 360;
$theme_width = empty( $content_width ) ? $default_width : ( $content_width - $outer );
$theme_height = empty( $content_width ) ? $default_height : round( ( $default_height * $theme_width ) / $default_width );
$data = array(
'type' => $atts['type'],
// Don't pass strings to JSON, will be truthy in JS.
'tracklist' => wp_validate_boolean( $atts['tracklist'] ),
'tracknumbers' => wp_validate_boolean( $atts['tracknumbers'] ),
'images' => wp_validate_boolean( $atts['images'] ),
'artists' => wp_validate_boolean( $atts['artists'] ),
);
$tracks = array();
foreach ( $attachments as $attachment ) {
$url = wp_get_attachment_url( $attachment->ID );
$ftype = wp_check_filetype( $url, wp_get_mime_types() );
$track = array(
'src' => $url,
'type' => $ftype['type'],
'title' => $attachment->post_title,
'caption' => $attachment->post_excerpt,
'description' => $attachment->post_content,
);
$track['meta'] = array();
$meta = wp_get_attachment_metadata( $attachment->ID );
if ( ! empty( $meta ) ) {
foreach ( wp_get_attachment_id3_keys( $attachment ) as $key => $label ) {
if ( ! empty( $meta[ $key ] ) ) {
$track['meta'][ $key ] = $meta[ $key ];
}
}
if ( 'video' === $atts['type'] ) {
if ( ! empty( $meta['width'] ) && ! empty( $meta['height'] ) ) {
$width = $meta['width'];
$height = $meta['height'];
$theme_height = round( ( $height * $theme_width ) / $width );
} else {
$width = $default_width;
$height = $default_height;
}
$track['dimensions'] = array(
'original' => compact( 'width', 'height' ),
'resized' => array(
'width' => $theme_width,
'height' => $theme_height,
),
);
}
}
if ( $atts['images'] ) {
$thumb_id = get_post_thumbnail_id( $attachment->ID );
if ( ! empty( $thumb_id ) ) {
list( $src, $width, $height ) = wp_get_attachment_image_src( $thumb_id, 'full' );
$track['image'] = compact( 'src', 'width', 'height' );
list( $src, $width, $height ) = wp_get_attachment_image_src( $thumb_id, 'thumbnail' );
$track['thumb'] = compact( 'src', 'width', 'height' );
} else {
$src = wp_mime_type_icon( $attachment->ID, '.svg' );
$width = 48;
$height = 64;
$track['image'] = compact( 'src', 'width', 'height' );
$track['thumb'] = compact( 'src', 'width', 'height' );
}
}
$tracks[] = $track;
}
$data['tracks'] = $tracks;
$safe_type = esc_attr( $atts['type'] );
$safe_style = esc_attr( $atts['style'] );
ob_start();
if ( ! $is_loaded ) {
/**
* Prints and enqueues playlist scripts, styles, and JavaScript templates.
*
* @since 3.9.0
*
* @param string $type Type of playlist. Possible values are 'audio' or 'video'.
* @param string $style The 'theme' for the playlist. Core provides 'light' and 'dark'.
*/
do_action( 'wp_playlist_scripts', $atts['type'], $atts['style'] );
$is_loaded = true;
}
?>
<div class="wp-playlist wp-<?php echo $safe_type; ?>-playlist wp-playlist-<?php echo $safe_style; ?>">
<div class="wp-playlist-current-item"></div>
< controls="controls" preload="none" width=""
><!--<?php echo $safe_type; ?-->>
<div class="wp-playlist-next"></div>
<div class="wp-playlist-prev"></div>
<noscript>
<ol>
$attachment ) {
printf( '<li>%s</li>', wp_get_attachment_link( $att_id ) );
}
?>
</ol>
</noscript>
<script type="application/json" class="wp-playlist-script"></script>
</div>
</pre><p class="wporg-dot-link-list"><a href="https://developer.wordpress.org/reference/files/wp-includes/media.php/">View all references</a> <a href="https://core.trac.wordpress.org/browser/tags/6.9.4/src/wp-includes/media.php#L3067">View on Trac</a> <a href="https://github.com/WordPress/wordpress-develop/blob/6.9.4/src/wp-includes/media.php#L3067-L3296">View on GitHub</a></p></section>
<section class="wp-block-wporg-code-reference-hooks"><h2 id="hooks" class="is-toc-heading wp-block-heading has-heading-5-font-size" tabindex="-1" ><a href="#hooks">Hooks</a></h2> <dl><dt class="wp-block-wporg-code-reference-title has-normal-font-size"><a href="https://developer.wordpress.org/reference/hooks/post_playlist/"><span class="hook-func">apply_filters</span>( ‘post_playlist’, <nobr><span class="arg-type">string</span> <span class="arg-name">$output</span></nobr>, <nobr><span class="arg-type">array</span> <span class="arg-name">$attr</span></nobr>, <nobr><span class="arg-type">int</span> <span class="arg-name">$instance</span></nobr> )</a></dt><dd><p>Filters the playlist output.</p>
</dd><dt class="wp-block-wporg-code-reference-title has-normal-font-size"><a href="https://developer.wordpress.org/reference/hooks/wp_playlist_scripts/"><span class="hook-func">do_action</span>( ‘wp_playlist_scripts’, <nobr><span class="arg-type">string</span> <span class="arg-name">$type</span></nobr>, <nobr><span class="arg-type">string</span> <span class="arg-name">$style</span></nobr> )</a></dt><dd><p>Prints and enqueues playlist scripts, styles, and JavaScript templates.</p>
</dd></dl></section>
<section class="wp-block-wporg-code-reference-related" data-nosnippet="true"><h2 id="related" class="is-toc-heading wp-block-heading has-heading-5-font-size" tabindex="-1" ><a href="#related">Related</a></h2> <section style="margin-top:var(--wp--preset--spacing--20)" class="wp-block-wporg-code-table" id="uses"><figure class="wp-block-table "><table><thead><tr><th scope="col">Uses</th><th scope="col">Description</th></tr></thead><tbody><tr class=""><td><a href="https://developer.wordpress.org/reference/functions/get_children/">get_children()</a><code>wp-includes/post.php
Retrieves all children of the post parent ID.
wp_validate_boolean()wp-includes/functions.php
Filters/validates a variable as a boolean.
is_feed()wp-includes/query.php
Determines whether the query is for a feed.
wp_check_filetype()wp-includes/functions.php
Retrieves the file type from the file name.
wp_get_mime_types()wp-includes/functions.php
Retrieves the list of mime types and file extensions.
shortcode_atts()wp-includes/shortcodes.php
Combines user attributes with known attributes and fill in defaults when needed.
get_post_thumbnail_id()wp-includes/post-thumbnail-template.php
Retrieves the post thumbnail ID.
wp_get_attachment_link()wp-includes/post-template.php
Retrieves an attachment page link using an image or icon, if possible.
post_password_required()wp-includes/post-template.php
Determines whether the post requires password and whether a correct password has been provided.
wp_get_attachment_id3_keys()wp-includes/media.php
Returns useful keys to use to lookup data from an attachment’s stored metadata.
wp_get_attachment_image_src()wp-includes/media.php
Retrieves an image to represent an attachment.
wp_mime_type_icon()wp-includes/post.php
Retrieves the icon for a MIME type or attachment.
wp_get_attachment_url()wp-includes/post.php
Retrieves the URL for an attachment.
wp_get_attachment_metadata()wp-includes/post.php
Retrieves attachment metadata for attachment ID.
get_posts()wp-includes/post.php
Retrieves an array of the latest posts, or posts matching the given criteria.
wp_json_encode()wp-includes/functions.php
Encodes a variable into JSON, with some confidence checks.
current_user_can()wp-includes/capabilities.php
Returns whether the current user has the specified capability.
esc_attr()wp-includes/formatting.php
Escaping for HTML attributes.
apply_filters()wp-includes/plugin.php
Calls the callback functions that have been added to a filter hook.
do_action()wp-includes/plugin.php
Calls the callback functions that have been added to an action hook.
get_post()wp-includes/post.php
Retrieves post data given a post ID or post object.
Changelog
| Version | Description |
|---|---|
| 3.9.0 | Introduced. |
Skip to note 2 content
David
FEEDBACK: This (and other) code references would be quite a bit more useful if they could include SCREEN SHOTS of what the resulting page looks like, where applicable.
In this case, four screenshots of PLAYLIST results would be appropriate:
– type=”audio” style=”light” (default)
– type=”audio” style=”dark”
– type=”video” (style=”light” – default)
– type=”video” style=”dark”
and other screenshots as needed to illustrate the results of various parameters.
NOTE: These would also be extremely useful on corresponding SHORTCODE pages of the codex.