0

I'm trying to integrate fullpage.js into a wordpress theme. To get the audio to keep playing between sections I need to add the data attribute data-keepplaying to the <audio> tag generated by wordpress.

However, I'm not sure how to hook into the built-in short code to add the data attribute. Basically, I'm looking for a way to modify the output of the audio shortcode so that I can do do this (or something similar) in my template:

<?php echo do_shortcode('[audio src="'.$audio_url.'" atts="data-keepplaying"]'); ?>
1

They're may be a more parsimonious way to achieve what you want, maybe with jQuery or a more heavily customized version of the code, but just keeping to WordPress core functions, you could try the following approach, which utilizes the wp_audio_shortcode_override filter.

I tested a version of the below using is_page() for the main conditional. You would substitute your page template filename in a conditional using get_page_template_slug() as shown:

/**
 * Use audio shortcode override filter selectively 
 * to replace built-in shortcode function with modified version
 * on pages using the specified template
 */

add_filter( 'wp_audio_shortcode_override', 'add_keep_playing_att_on_these', 10, 4 );

function add_keep_playing_att_on_these($override, $attr, $content, $instance) {

    if ( 'page-audio.php' === get_page_template_slug( get_the_ID() ) ) {

        /**
         * EXCEPT AS NOTED
         * FROM HERE UP TO THE RETURN STATEMENTS
         * function mostly re-produces audio shortcode function from media.php
         * I removed the html filter from the original code, but may return later and put it back!
         **/

        $default_types = wp_get_audio_extensions();
        $defaults_atts = array(
            'src'      => '',
            'loop'     => '',
            'autoplay' => '',
            'preload'  => 'none',
            'class'    => 'wp-audio-shortcode',
            'style'    => 'width: 100%;'
        );
        foreach ( $default_types as $type ) {
            $defaults_atts[$type] = '';
        }

        $atts = shortcode_atts( $defaults_atts, $attr, 'audio' );

        $primary = false;
        if ( ! empty( $atts['src'] ) ) {
            $type = wp_check_filetype( $atts['src'], wp_get_mime_types() );
            if ( ! in_array( strtolower( $type['ext'] ), $default_types ) ) {
                return sprintf( '<a class="wp-embedded-audio" href="%s">%s</a>', esc_url( $atts['src'] ), esc_html( $atts['src'] ) );
            }
            $primary = true;
            array_unshift( $default_types, 'src' );
        } else {
            foreach ( $default_types as $ext ) {
                if ( ! empty( $atts[ $ext ] ) ) {
                    $type = wp_check_filetype( $atts[ $ext ], wp_get_mime_types() );
                    if ( strtolower( $type['ext'] ) === $ext ) {
                        $primary = true;
                    }
                }
            }
        }

        if ( ! $primary ) {
            $audios = get_attached_media( 'audio', $post_id );
            if ( empty( $audios ) ) {
                return;
            }

            $audio = reset( $audios );
            $atts['src'] = wp_get_attachment_url( $audio->ID );
            if ( empty( $atts['src'] ) ) {
                return;
            }

            array_unshift( $default_types, 'src' );
        }

        /**
         * Filters the media library used for the audio shortcode.
         *
         * @since 3.6.0
         *
         * @param string $library Media library used for the audio shortcode.
         */
        $library = apply_filters( 'wp_audio_shortcode_library', 'mediaelement' );
        if ( 'mediaelement' === $library && did_action( 'init' ) ) {
            wp_enqueue_style( 'wp-mediaelement' );
            wp_enqueue_script( 'wp-mediaelement' );
        }

        /**
         * Filters the class attribute for the audio shortcode output container.
         *
         * @since 3.6.0
         *
         * @param string $class CSS class or list of space-separated classes.
         */
        $atts['class'] = apply_filters( 'wp_audio_shortcode_class', $atts['class'] );

        $html_atts = array(
            'class'    => $atts['class'],
            'id'       => sprintf( 'audio-%d-%d', $post_id, $instance ),
            'loop'     => wp_validate_boolean( $atts['loop'] ),
            'autoplay' => wp_validate_boolean( $atts['autoplay'] ),
            'preload'  => $atts['preload'],
            'style'    => $atts['style'],
        );

        // These ones should just be omitted altogether if they are blank
        foreach ( array( 'loop', 'autoplay', 'preload' ) as $a ) {
            if ( empty( $html_atts[$a] ) ) {
                unset( $html_atts[$a] );
            }
        }

        $attr_strings = array();
        foreach ( $html_atts as $k => $v ) {
            $attr_strings[] = $k . '="' . esc_attr( $v ) . '"';
        }

        $html = '';
        if ( 'mediaelement' === $library && 1 === $instance ) {
            $html .= "<!--[if lt IE 9]><script>document.createElement('audio');</script><![endif]-->\n";
        }

        /****************************************************************
         * ADD data-keepplaying ATTRIBUTE TO AUDIO HTML         
         * THIS IS THE THE ONLY SIGNIFICANT ALTERATION IN THE BASIC AUDIO SHORTCODE
         ***************************************************************/

        $html .= sprintf( '<audio %s controls="controls" data-keepplaying>', join( ' ', $attr_strings ) );

        $fileurl = '';
        $source = '<source type="%s" src="%s" />';
        foreach ( $default_types as $fallback ) {
            if ( ! empty( $atts[ $fallback ] ) ) {
                if ( empty( $fileurl ) ) {
                    $fileurl = $atts[ $fallback ];
                }
                $type = wp_check_filetype( $atts[ $fallback ], wp_get_mime_types() );
                $url = add_query_arg( '_', $instance, $atts[ $fallback ] );
                $html .= sprintf( $source, $type['type'], esc_url( $url ) );
            }
        }

        if ( 'mediaelement' === $library ) {
            $html .= wp_mediaelement_fallback( $fileurl );
        }
        $html .= '</audio>';

        return $html ;

    } else {

        return $override ;

    }

}
  • I had thought of doing this after I posted, and while it works it seems like overkill to have to repeat the entire function just to add one small attribute! Settled on using jQuery to add the attribute as it only took one very short line of code! $('audio').attr('data-keepplaying', ''); – Ralphonz Nov 26 '17 at 16:05
  • I mostly agree. I didn't try a jQuery solution because a) I wasn't sure it would work, and b) without knowing more about your application, I didn't know whether it would mean writing and enqueuing a separate file, or how it should be targeted to the intended template. Though my solution takes up space, I doubt it adds meaningfully if at all to processing time, and, since it's all in one independent filter function, it would be easily maintainable and modifiable. Anyway, I think you ought to present your contextualized code in a self-answer! – CK MacLeod Nov 26 '17 at 18:39
  • note as alternative that you could add "data-keepplaying" as an "atts" argument instead, and proceed from there with a "do_shortcode" implementation in the page template - but that would require altering at least two files. – CK MacLeod Nov 26 '17 at 18:45
  • What do you mean by adding an atts argument? Thats the first thing I tried? I'm using do_shortocde in my page template anyway and what I'd like to do be able to add attributes via that but as in my original post adding atts="data-keepplaying" doesn't work? – Ralphonz Nov 27 '17 at 11:00
  • All I meant was that, while overriding and replacing the shortcode as above, you could add a true/false data-keepplaying "att" to it instead of always adding "data-keepplaying." You could even remove the conditional, and just add the att in the replacement version. There might be other reasons not to go this route, I think, but I don't know how weighty you'd find them. I generally default to doing as little as possible, as restrictively as possible, to Core functions. – CK MacLeod Nov 27 '17 at 22:14

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.