I’d like to add a download button to the core wp audio player (mediaelement.js).
How can I do that simply? Any suggestions?
2 Answers
How to use a custom playlist template:
You can overwrite the playlist template with your own template:
/**
* Remove the native playlist template and load our custom template
* @link http://wordpress.stackexchange.com/q/141767/26350
*/
add_action( 'wp_playlist_scripts', 'wpse_141767_wp_playlist_scripts' );
function wpse_141767_wp_playlist_scripts()
{
remove_action( 'wp_footer', 'wp_underscore_playlist_templates', 0 );
add_action( 'wp_footer', 'wpse_141767_wp_underscore_playlist_templates', 0 );
}
where our modified template is defined as:
/**
* Our custom playlist template.
*/
function wpse_141767_wp_underscore_playlist_templates() {
?>
<script type="text/html" id="tmpl-wp-playlist-current-item">
<# if ( data.image ) { #>
<img src="https://wordpress.stackexchange.com/questions/141767/{{ data.thumb.src }}"/>
<# } #>
<div class="wp-playlist-caption">
<span class="wp-playlist-item-meta wp-playlist-item-title">“{{ data.title }}”</span>
<# if ( data.meta.album ) { #><span class="wp-playlist-item-meta wp-playlist-item-album">{{ data.meta.album }}</span><# } #>
<# if ( data.meta.artist ) { #><span class="wp-playlist-item-meta wp-playlist-item-artist">{{ data.meta.artist }}</span><# } #>
</div>
</script>
<script type="text/html" id="tmpl-wp-playlist-item">
<div class="wp-playlist-item">
<a class="wp-playlist-caption" href="https://wordpress.stackexchange.com/questions/141767/{{ data.src }}">
{{ data.index ? ( data.index + '. ' ) : '' }}
<# if ( data.caption ) { #>
{{ data.caption }}
<# } else { #>
<span class="wp-playlist-item-title">“{{{ data.title }}}”</span>
<# if ( data.artists && data.meta.artist ) { #>
<span class="wp-playlist-item-artist"> — {{ data.meta.artist }}</span>
<# } #>
<# } #>
</a>
<# if ( data.meta.length_formatted ) { #>
<div class="wp-playlist-item-length">{{ data.meta.length_formatted }}</div>
<# } #>
</div>
<!-- BEGIN CHANGES -->
<a href="https://wordpress.stackexchange.com/questions/141767/{{ data.src }}" class="wpse-download" download="">download</a>
<!-- END CHANGES -->
</script>
<?php
}
where we added this part at the end:
<!-- BEGIN CHANGES -->
(<a href="https://wordpress.stackexchange.com/questions/141767/{{ data.src }}" class="wpse-download" download="">download</a>)
<!-- END CHANGES -->
You might also need to add a special url to download the files.
The reason why I didn’t add it within the div.wp-playlist-item
selector, is because everything that’s clicked on inside it, will start the player. The reason is this part of the /wp-includes/js/mediaelement/wp-playlist.js
file:
events : {
'click .wp-playlist-item' : 'clickTrack',
'click .wp-playlist-next' : 'next',
'click .wp-playlist-prev' : 'prev'
},
clickTrack : function (e) {
e.preventDefault();
this.index = this.$( '.wp-playlist-item' ).index( e.currentTarget );
this.setCurrent();
},
Here’s the screenshot of our modified playlist template in action:
You could try some custom CSS to modify this to your needs.
Here’s one kind of hack, that might need adjustments depending on the current theme:
<style>
.wpse-download {
margin-top: -22px;
margin-left: -16px;
position: absolute;
}
.wp-playlist {
padding: 25px;
}
</style>
with:
<!-- BEGIN CHANGES -->
<a href="https://wordpress.stackexchange.com/questions/141767/{{ data.src }}" class="wpse-download" download="">
<i class="fa fa-download" aria-hidden="true"></i>
</a>
<!-- END CHANGES -->
in the presence of Font Awesome.
Further customization:
You might also consider enqueuing your own version of the wp-playlist.js
file where you replace:
'click .wp-playlist-item' : 'clickTrack',
with for example:
'click a.wp-playlist-item-caption' : 'clickTrack',
to be able to have the download link in the same row as the song title.
Update:
Updated the screenshots and added another example.
To make sure the file is downloaded and not displayed in the browser, we can use the download
link attribute. I’ve updated the above with:
(<a href="https://wordpress.stackexchange.com/questions/141767/{{ data.src }}" download="">download</a>)
It seems that the empty value will download it as current file name.