WP Recipe Maker – Video Instructions

If you have a video specified for your recipe / how-to card, and you have specified video timestamps for each step, this will include an embedded video at each step.

function be_wprm_video_instructions( $atts ) { $atts = shortcode_atts( [ 'id' => false, 'header' => 'Instructions', 'header_tag' => 'h2', 'group_tag' => 'h4', 'image_position' => 'before', 'image_alignment' => 'center', 'image_size' => 'medium', ], $atts ); $recipe = WPRM_Template_Shortcodes::get_recipe( $atts['id'] ); if ( ! $recipe || ! $recipe->instructions() ) { return ''; } $video = $recipe->video(); // Output. $classes = array( 'wprm-recipe-instructions-container', ); $output = '<div class="' . implode( ' ', $classes ) . '">'; if ( $atts['header'] ) { $classes = array( 'wprm-recipe-header', 'wprm-recipe-instructions-header', ); $tag = trim( $atts['header_tag'] ); $output .= '<' . $tag . ' class="' . implode( ' ', $classes ) . '">' . __( $atts['header'], 'wp-recipe-maker' ) . '</' . $tag . '>'; } $instructions = $recipe->instructions(); foreach ( $instructions as $group_index => $instruction_group ) { $output .= '<div class="wprm-recipe-instruction-group">'; if ( $instruction_group['name'] ) { $classes = array( 'wprm-recipe-group-name', 'wprm-recipe-instruction-group-name', ); $tag = trim( $atts['group_tag'] ); $output .= '<' . $tag . ' class="' . implode( ' ', $classes ) . '">' . $instruction_group['name'] . '</' . $tag . '>'; } $output .= '<ul class="wprm-recipe-instructions">'; foreach ( $instruction_group['instructions'] as $index => $instruction ) { $output .= '<li id="wprm-recipe-' . $recipe->id() . '-step-' . $group_index . '-' . $index . '" class="wprm-recipe-instruction">'; if( !empty( $video ) && !empty( $instruction['video'] ) ) { $step_video = str_replace( '" frameborder="0"', '&start=' . be_video_start( $instruction['video'] ) . '" frameborder="0"', $video ); $output .= '<div class="wprm-recipe-instructions-video">' . $step_video . '</div>'; } if ( 'before' === $atts['image_position'] && $instruction['image'] ) { $output .= '<div class="wprm-recipe-instruction-image" style="text-align: ' . $atts['image_alignment'] . ';">' . be_wprm_instruction_image( $recipe, $instruction, $atts['image_size'] ) . '</div> '; } if ( $instruction['text'] ) { $output .= '<div class="wprm-recipe-instruction-text">' . wpautop( $instruction['text'] ) . '</div> '; } if ( 'after' === $atts['image_position'] && $instruction['image'] ) { $output .= '<div class="wprm-recipe-instruction-image" style="text-align: ' . $atts['image_alignment'] . ';">' . be_wprm_instruction_image( $recipe, $instruction, $atts['image_size'] ) . '</div> '; } $output .= '</li>'; } $output .= '</ul>'; $output .= '</div>'; } $output .= '</div>'; return $output; } add_shortcode( 'be_wprm_video_instructions', 'be_wprm_video_instructions' ); /** * Output an instruction image. * * @since 3.3.0 * @param mixed $recipe Recipe to output the instruction for. * @param mixed $instruction Instruction to output the image for. * @param mixed $default_image_size Default image size to use. */ function be_wprm_instruction_image( $recipe, $instruction, $default_image_size ) { $settings_size = 'legacy' === WPRM_Settings::get( 'recipe_template_mode' ) ? WPRM_Settings::get( 'template_instruction_image' ) : false; $size = $settings_size ? $settings_size : $default_image_size; preg_match( '/^(\d+)x(\d+)$/i', $size, $match ); if ( ! empty( $match ) ) { $size = array( intval( $match[1] ), intval( $match[2] ) ); } $img = wp_get_attachment_image( $instruction['image'], $size ); // Prevent instruction image from getting stretched in Gutenberg preview. if ( isset( $GLOBALS['wp']->query_vars['rest_route'] ) && '/wp/v2/block-renderer/wp-recipe-maker/recipe' === $GLOBALS['wp']->query_vars['rest_route'] ) { $image_data = wp_get_attachment_image_src( $instruction['image'], $size ); if ( $image_data[1] ) { $style = 'max-width: ' . $image_data[1] . 'px;'; if ( false !== stripos( $img, ' style="' ) ) { $img = str_ireplace( ' style="', ' style="' . $style, $img ); } else { $img = str_ireplace( '<img ', '<img style="' . $style . '" ', $img ); } } } // Disable instruction image pinning. if ( WPRM_Settings::get( 'pinterest_nopin_instruction_image' ) ) { $img = str_ireplace( '<img ', '<img data-pin-nopin="true" ', $img ); } // Clickable images. if ( WPRM_Settings::get( 'instruction_image_clickable' ) ) { $settings_size = WPRM_Settings::get( 'clickable_image_size' ); preg_match( '/^(\d+)x(\d+)$/i', $settings_size, $match ); if ( ! empty( $match ) ) { $size = array( intval( $match[1] ), intval( $match[2] ) ); } else { $size = $settings_size; } $clickable_image = wp_get_attachment_image_src( $instruction['image'], $size ); $clickable_image_url = $clickable_image && isset( $clickable_image[0] ) ? $clickable_image[0] : ''; if ( $clickable_image_url ) { $img = '<a href="' . esc_url( $clickable_image_url ) . '">' . $img . '</a>'; } } return $img; } function be_video_start( $video ) { if( empty( $video['start'] ) ) return 0; $parts = array_reverse( explode( ':', $video['start'] ) ); $seconds = $parts[0]; if( !empty( $parts[1] ) ) $seconds += $parts[1] * 60; if( !empty( $parts[2] ) ) $seconds += $parts[2] * HOUR_IN_SECONDS; return $seconds; }
Bill Erickson

Bill Erickson is a freelance WordPress developer and a contributing developer to the Genesis framework. For the past 14 years he has worked with attorneys, publishers, corporations, and non-profits, building custom websites tailored to their needs and goals.

Ready to upgrade your website?

I build custom WordPress websites that look great and are easy to manage.

Let's Talk