Themes: Enable video in custom headers.
This adds the ability for themes to add support for videos in custom headers by passing `'video' => true` as an argument when adding theme support for custom headers. Custom video headers are managed through the “Header Visuals” (i.e. “Header Image”) panel in the Customizer where you can select a video from the media library or set a URL to an external video (YouTube for now) for use in custom headers. This introduces several new functions: `has_header_video()` – Check whether a header video is set or not. `get_header_video_url()` – Retrieve header video URL for custom header. `the_header_video_url()` – Display header video URL. `get_header_video_settings()` – Retrieve header video settings. `has_custom_header()` – Check whether a custom header is set or not. `get_custom_header_markup()` – Retrieve the markup for a custom header. `the_custom_header_markup()` – Print the markup for a custom header. And a new file, `wp-includes/js/wp-custom-header.js` that handles loading videos in custom headers. This also enables video headers in the Twenty Seventeen and Twenty Fourteen themes. Props davidakennedy, celloexpressions, bradyvercher, laurelfulford, joemcgill. Fixes #38172. Built from https://develop.svn.wordpress.org/trunk@38985 git-svn-id: http://core.svn.wordpress.org/trunk@38928 1a063a9b-81f0-0310-95a4-ce76da25c4cd
This commit is contained in:
parent
7b0abd1cea
commit
030bc377dd
|
@ -434,7 +434,7 @@ function twentyfourteen_body_classes( $classes ) {
|
|||
$classes[] = 'group-blog';
|
||||
}
|
||||
|
||||
if ( get_header_image() ) {
|
||||
if ( get_header_image() || function_exists( 'has_header_video' ) && has_header_video() ) {
|
||||
$classes[] = 'header-image';
|
||||
} elseif ( ! in_array( $GLOBALS['pagenow'], array( 'wp-activate.php', 'wp-signup.php' ) ) ) {
|
||||
$classes[] = 'masthead-fixed';
|
||||
|
|
|
@ -32,7 +32,11 @@
|
|||
|
||||
<body <?php body_class(); ?>>
|
||||
<div id="page" class="hfeed site">
|
||||
<?php if ( get_header_image() ) : ?>
|
||||
<?php if ( function_exists( 'has_header_video' ) && has_header_video() ) : ?>
|
||||
<div id="site-header">
|
||||
<?php the_custom_header_markup(); ?>
|
||||
</div>
|
||||
<?php elseif ( get_header_image() ) : ?>
|
||||
<div id="site-header">
|
||||
<a href="<?php echo esc_url( home_url( '/' ) ); ?>" rel="home">
|
||||
<img src="<?php header_image(); ?>" width="<?php echo get_custom_header()->width; ?>" height="<?php echo get_custom_header()->height; ?>" alt="<?php echo esc_attr( get_bloginfo( 'name', 'display' ) ); ?>">
|
||||
|
|
|
@ -40,6 +40,7 @@ function twentyfourteen_custom_header_setup() {
|
|||
'width' => 1260,
|
||||
'height' => 240,
|
||||
'flex-height' => true,
|
||||
'video' => true,
|
||||
'wp-head-callback' => 'twentyfourteen_header_style',
|
||||
'admin-head-callback' => 'twentyfourteen_admin_header_style',
|
||||
'admin-preview-callback' => 'twentyfourteen_admin_header_image',
|
||||
|
|
|
@ -16,9 +16,11 @@
|
|||
*/
|
||||
function twentyfourteen_customize_register( $wp_customize ) {
|
||||
// Add postMessage support for site title and description.
|
||||
$wp_customize->get_setting( 'blogname' )->transport = 'postMessage';
|
||||
$wp_customize->get_setting( 'blogdescription' )->transport = 'postMessage';
|
||||
$wp_customize->get_setting( 'header_textcolor' )->transport = 'postMessage';
|
||||
$wp_customize->get_setting( 'blogname' )->transport = 'postMessage';
|
||||
$wp_customize->get_setting( 'blogdescription' )->transport = 'postMessage';
|
||||
$wp_customize->get_setting( 'header_textcolor' )->transport = 'postMessage';
|
||||
$wp_customize->get_setting( 'header_image' )->transport = 'postMessage';
|
||||
$wp_customize->get_setting( 'header_image_data' )->transport = 'postMessage';
|
||||
|
||||
if ( isset( $wp_customize->selective_refresh ) ) {
|
||||
$wp_customize->selective_refresh->add_partial( 'blogname', array(
|
||||
|
|
|
@ -95,15 +95,20 @@
|
|||
*/
|
||||
if ( _window.width() > 781 ) {
|
||||
var mastheadHeight = $( '#masthead' ).height(),
|
||||
toolbarOffset, mastheadOffset;
|
||||
mastheadOffset;
|
||||
|
||||
if ( mastheadHeight > 48 ) {
|
||||
body.removeClass( 'masthead-fixed' );
|
||||
}
|
||||
|
||||
mastheadOffset = $( '#site-header' ).height();
|
||||
|
||||
if ( body.is( '.header-image' ) ) {
|
||||
toolbarOffset = body.is( '.admin-bar' ) ? $( '#wpadminbar' ).height() : 0;
|
||||
mastheadOffset = $( '#masthead' ).offset().top - toolbarOffset;
|
||||
|
||||
// Recaculate the header height when a custom header loads.
|
||||
$( 'body' ).on( 'wp-custom-header-video-loaded', function() {
|
||||
mastheadOffset = $( '#site-header' ).height();
|
||||
} );
|
||||
|
||||
_window.on( 'scroll.twentyfourteen', function() {
|
||||
if ( _window.scrollTop() > mastheadOffset && mastheadHeight < 49 ) {
|
||||
|
@ -112,6 +117,13 @@
|
|||
body.removeClass( 'masthead-fixed' );
|
||||
}
|
||||
} );
|
||||
|
||||
// Update masthead offset after a selective refresh.
|
||||
if ( 'undefined' !== typeof wp && wp.customize && wp.customize.selectiveRefresh ) {
|
||||
wp.customize.selectiveRefresh.bind( 'partial-content-rendered', function() {
|
||||
mastheadOffset = $( '#site-header' ).height();
|
||||
} );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -88,6 +88,7 @@ canvas,
|
|||
video {
|
||||
display: inline-block;
|
||||
max-width: 100%;
|
||||
height: auto;
|
||||
}
|
||||
|
||||
html {
|
||||
|
@ -608,6 +609,11 @@ video {
|
|||
max-width: 100%;
|
||||
}
|
||||
|
||||
#wp-custom-header iframe,
|
||||
#wp-custom-header video {
|
||||
margin-bottom: -8px;
|
||||
}
|
||||
|
||||
p > embed,
|
||||
p > iframe,
|
||||
p > object,
|
||||
|
|
|
@ -68,6 +68,12 @@ img {
|
|||
padding: 45px 0;
|
||||
}
|
||||
|
||||
.has-header-image .custom-header-image img,
|
||||
.has-header-image .custom-header-image video {
|
||||
left: 0;
|
||||
top: 0;
|
||||
}
|
||||
|
||||
.site-title {
|
||||
font-size: 36px;
|
||||
font-weight: bolder;
|
||||
|
|
|
@ -14,31 +14,32 @@
|
|||
|
||||
?>
|
||||
|
||||
</div><!-- #content -->
|
||||
</div><!-- #content -->
|
||||
|
||||
<footer id="colophon" class="site-footer" role="contentinfo">
|
||||
<div class="wrap">
|
||||
<?php
|
||||
get_template_part( 'template-parts/footer/footer', 'widgets' );
|
||||
<footer id="colophon" class="site-footer" role="contentinfo">
|
||||
<div class="wrap">
|
||||
<?php
|
||||
get_template_part( 'template-parts/footer/footer', 'widgets' );
|
||||
|
||||
if ( has_nav_menu( 'social' ) ) : ?>
|
||||
<nav class="social-navigation" role="navigation" aria-label="<?php _e( 'Footer Social Links Menu', 'twentyseventeen' ); ?>">
|
||||
<?php
|
||||
wp_nav_menu( array(
|
||||
'theme_location' => 'social',
|
||||
'menu_class' => 'social-links-menu',
|
||||
'depth' => 1,
|
||||
'link_before' => '<span class="screen-reader-text">',
|
||||
'link_after' => '</span>' . twentyseventeen_get_svg( array( 'icon' => 'chain' ) ),
|
||||
) );
|
||||
?>
|
||||
</nav><!-- .social-navigation -->
|
||||
<?php endif;
|
||||
if ( has_nav_menu( 'social' ) ) : ?>
|
||||
<nav class="social-navigation" role="navigation" aria-label="<?php _e( 'Footer Social Links Menu', 'twentyseventeen' ); ?>">
|
||||
<?php
|
||||
wp_nav_menu( array(
|
||||
'theme_location' => 'social',
|
||||
'menu_class' => 'social-links-menu',
|
||||
'depth' => 1,
|
||||
'link_before' => '<span class="screen-reader-text">',
|
||||
'link_after' => '</span>' . twentyseventeen_get_svg( array( 'icon' => 'chain' ) ),
|
||||
) );
|
||||
?>
|
||||
</nav><!-- .social-navigation -->
|
||||
<?php endif;
|
||||
|
||||
get_template_part( 'template-parts/footer/site', 'info' );
|
||||
?>
|
||||
</div><!-- .wrap -->
|
||||
</footer><!-- #colophon -->
|
||||
get_template_part( 'template-parts/footer/site', 'info' );
|
||||
?>
|
||||
</div><!-- .wrap -->
|
||||
</footer><!-- #colophon -->
|
||||
</div><!-- .site-content-contain -->
|
||||
</div><!-- #page -->
|
||||
<?php wp_footer(); ?>
|
||||
|
||||
|
|
|
@ -49,4 +49,5 @@
|
|||
endif;
|
||||
?>
|
||||
|
||||
<div id="content" class="site-content">
|
||||
<div class="site-content-contain">
|
||||
<div id="content" class="site-content">
|
||||
|
|
|
@ -39,6 +39,7 @@ function twentyseventeen_custom_header_setup() {
|
|||
'width' => 2000,
|
||||
'height' => 1200,
|
||||
'flex-height' => true,
|
||||
'video' => true,
|
||||
'wp-head-callback' => 'twentyseventeen_header_style',
|
||||
) ) );
|
||||
|
||||
|
|
|
@ -13,9 +13,11 @@
|
|||
* @param WP_Customize_Manager $wp_customize Theme Customizer object.
|
||||
*/
|
||||
function twentyseventeen_customize_register( $wp_customize ) {
|
||||
$wp_customize->get_setting( 'blogname' )->transport = 'postMessage';
|
||||
$wp_customize->get_setting( 'blogdescription' )->transport = 'postMessage';
|
||||
$wp_customize->get_setting( 'header_textcolor' )->transport = 'postMessage';
|
||||
$wp_customize->get_setting( 'blogname' )->transport = 'postMessage';
|
||||
$wp_customize->get_setting( 'blogdescription' )->transport = 'postMessage';
|
||||
$wp_customize->get_setting( 'header_textcolor' )->transport = 'postMessage';
|
||||
$wp_customize->get_setting( 'header_image' )->transport = 'postMessage';
|
||||
$wp_customize->get_setting( 'header_image_data' )->transport = 'postMessage';
|
||||
|
||||
$wp_customize->selective_refresh->add_partial( 'blogname', array(
|
||||
'selector' => '.site-title a',
|
||||
|
|
|
@ -35,7 +35,7 @@ function twentyseventeen_body_classes( $classes ) {
|
|||
}
|
||||
|
||||
// Add a class if there is a custom header.
|
||||
if ( has_header_image() ) {
|
||||
if ( has_header_image() || has_header_video() && is_front_page() ) {
|
||||
$classes[] = 'has-header-image';
|
||||
}
|
||||
|
||||
|
|
|
@ -1314,6 +1314,7 @@ a:hover .nav-title,
|
|||
border-top: 1px solid #eee;
|
||||
font-size: 16px;
|
||||
font-size: 1rem;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.navigation-top .wrap {
|
||||
|
@ -1555,8 +1556,10 @@ body {
|
|||
|
||||
.site-branding {
|
||||
padding: 1em 0;
|
||||
position: relative;
|
||||
-webkit-transition: margin-bottom 0.2s;
|
||||
transition: margin-bottom 0.2s;
|
||||
z-index: 3;
|
||||
}
|
||||
|
||||
.site-branding a {
|
||||
|
@ -1650,15 +1653,13 @@ body:not(.title-tagline-hidden) .site-branding-text {
|
|||
}
|
||||
|
||||
.custom-header-image {
|
||||
background-position: center center;
|
||||
background-repeat: no-repeat;
|
||||
-webkit-background-size: cover;
|
||||
background-size: cover;
|
||||
bottom: 0;
|
||||
left: 0;
|
||||
overflow: hidden;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
top: 0;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
.custom-header-image:before {
|
||||
|
@ -1674,10 +1675,35 @@ body:not(.title-tagline-hidden) .site-branding-text {
|
|||
left: 0;
|
||||
position: absolute;
|
||||
right: 0;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.has-header-image:not(.twentyseventeen-front-page):not(.home) .custom-header-image {
|
||||
background-position: center bottom;
|
||||
.has-header-image .custom-header-image img,
|
||||
.has-header-image .custom-header-image video,
|
||||
.has-header-image .custom-header-image iframe {
|
||||
position: fixed;
|
||||
height: auto;
|
||||
left: 50%;
|
||||
max-width: 1000%;
|
||||
min-height: 100%;
|
||||
min-width: 100%;
|
||||
min-width: 100vw; /* vw prevents 1px gap on left that 100% has */
|
||||
width: auto;
|
||||
top: 50%;
|
||||
-ms-transform: translateX(-50%) translateY(-50%);
|
||||
-moz-transform: translateX(-50%) translateY(-50%);
|
||||
-webkit-transform: translateX(-50%) translateY(-50%);
|
||||
transform: translateX(-50%) translateY(-50%);
|
||||
}
|
||||
|
||||
.has-header-image:not(.twentyseventeen-front-page):not(.home) .custom-header-image img {
|
||||
bottom: 0;
|
||||
position: absolute;
|
||||
top: auto;
|
||||
-ms-transform: translateX(-50%) translateY(0);
|
||||
-moz-transform: translateX(-50%) translateY(0);
|
||||
-webkit-transform: translateX(-50%) translateY(0);
|
||||
transform: translateX(-50%) translateY(0);
|
||||
}
|
||||
|
||||
body:not(.has-header-image) .custom-header-image {
|
||||
|
@ -1777,6 +1803,11 @@ body:not(.has-header-image) .custom-header-image {
|
|||
## Regular Content
|
||||
--------------------------------------------------------------*/
|
||||
|
||||
.site-content-contain {
|
||||
background-color: #fff;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.site-content {
|
||||
padding: 2.5em 0 0;
|
||||
}
|
||||
|
@ -2642,7 +2673,8 @@ h2.widget-title {
|
|||
# Media
|
||||
--------------------------------------------------------------*/
|
||||
|
||||
img {
|
||||
img,
|
||||
video {
|
||||
height: auto; /* Make sure images are scaled correctly. */
|
||||
max-width: 100%; /* Adhere to container width. */
|
||||
}
|
||||
|
@ -3287,7 +3319,6 @@ article.panel-placeholder {
|
|||
|
||||
.has-header-image.twentyseventeen-front-page .custom-header,
|
||||
.has-header-image.home.blog .custom-header {
|
||||
display: block;
|
||||
min-height: 0;
|
||||
}
|
||||
|
||||
|
@ -3296,6 +3327,12 @@ article.panel-placeholder {
|
|||
position: relative;
|
||||
}
|
||||
|
||||
.twentyseventeen-front-page.has-header-image .custom-header-image,
|
||||
.home.blog.has-header-image .custom-header-image {
|
||||
height: 0;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.has-header-image:not(.twentyseventeen-front-page):not(.home) .custom-header-image {
|
||||
bottom: 0;
|
||||
height: auto;
|
||||
|
@ -3305,13 +3342,6 @@ article.panel-placeholder {
|
|||
top: 0;
|
||||
}
|
||||
|
||||
.twentyseventeen-front-page.has-header-image .custom-header-image,
|
||||
.home.blog.has-header-image .custom-header-image {
|
||||
height: 0;
|
||||
padding-top: 66%;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.custom-logo-link {
|
||||
padding-right: 2em;
|
||||
}
|
||||
|
@ -3591,7 +3621,8 @@ article.panel-placeholder {
|
|||
height: 1200px;
|
||||
height: 100vh;
|
||||
max-height: 100%;
|
||||
padding: 10% 0;
|
||||
overflow: hidden;
|
||||
/* padding: 10% 0; */
|
||||
}
|
||||
|
||||
.twentyseventeen-front-page.has-header-image .custom-header-image:before,
|
||||
|
@ -3938,11 +3969,6 @@ article.panel-placeholder {
|
|||
|
||||
@media screen and ( min-width: 55em ) {
|
||||
|
||||
.twentyseventeen-front-page.has-header-image .custom-header-image,
|
||||
.home.blog.has-header-image .custom-header-image {
|
||||
background-attachment: fixed;
|
||||
}
|
||||
|
||||
.panel-image {
|
||||
background-attachment: fixed;
|
||||
}
|
||||
|
|
|
@ -14,12 +14,17 @@
|
|||
$header_image = get_header_image();
|
||||
|
||||
// Check if Custom Header image has been added.
|
||||
if ( ! empty( $header_image ) ) : ?>
|
||||
if ( has_custom_header() ) :
|
||||
?>
|
||||
|
||||
<div class="custom-header-image" style="background-image: url(<?php echo esc_url( $header_image ); ?>)"></div>
|
||||
<?php // Output the full custom header - video and/or image fallback. ?>
|
||||
<div class="custom-header-image">
|
||||
<?php the_custom_header_markup(); ?>
|
||||
</div>
|
||||
<?php get_template_part( 'template-parts/header/site', 'branding' ); ?>
|
||||
|
||||
<?php else : ?>
|
||||
|
||||
<?php // Otherwise, show a blank header. ?>
|
||||
<div class="custom-header-simple">
|
||||
<?php get_template_part( 'template-parts/header/site', 'branding' ); ?>
|
||||
|
|
|
@ -363,6 +363,9 @@ final class WP_Customize_Manager {
|
|||
add_action( 'customize_controls_print_footer_scripts', array( $this, 'render_section_templates' ), 1 );
|
||||
add_action( 'customize_controls_print_footer_scripts', array( $this, 'render_control_templates' ), 1 );
|
||||
|
||||
// Export header video settings with the partial response.
|
||||
add_filter( 'customize_render_partials_response', array( $this, 'export_header_video_settings' ), 10, 3 );
|
||||
|
||||
// Export the settings to JS via the _wpCustomizeSettings variable.
|
||||
add_action( 'customize_controls_print_footer_scripts', array( $this, 'customize_pane_settings' ), 1000 );
|
||||
|
||||
|
@ -3249,12 +3252,54 @@ final class WP_Customize_Manager {
|
|||
|
||||
/* Custom Header */
|
||||
|
||||
if ( current_theme_supports( 'custom-header', 'video' ) ) {
|
||||
$title = __( 'Header Visuals' );
|
||||
$description = __( 'If you add a video, the image will be used as a fallback while the video loads.' );
|
||||
$width = absint( get_theme_support( 'custom-header', 'width' ) );
|
||||
$height = absint( get_theme_support( 'custom-header', 'height' ) );
|
||||
if ( $width && $height ) {
|
||||
/* translators: %s: header size in pixels */
|
||||
$control_description = sprintf( __( 'Upload your video in <code>.mp4</code> format and minimize its file size for best results. Your theme recommends dimensions of %s pixels.' ),
|
||||
sprintf( '<strong>%s × %s</strong>', $width, $height )
|
||||
);
|
||||
} elseif ( $width ) {
|
||||
/* translators: %s: header width in pixels */
|
||||
$control_description = sprintf( __( 'Upload your video in <code>.mp4</code> format and minimize its file size for best results. Your theme recommends a width of %s pixels.' ),
|
||||
sprintf( '<strong>%s</strong>', $width )
|
||||
);
|
||||
} else {
|
||||
/* translators: %s: header height in pixels */
|
||||
$control_description = sprintf( __( 'Upload your video in <code>.mp4</code> format and minimize its file size for best results. Your theme recommends a height of %s pixels.' ),
|
||||
sprintf( '<strong>%s</strong>', $height )
|
||||
);
|
||||
}
|
||||
} else {
|
||||
$title = __( 'Header Image' );
|
||||
$description = '';
|
||||
$control_description = '';
|
||||
}
|
||||
|
||||
$this->add_section( 'header_image', array(
|
||||
'title' => __( 'Header Image' ),
|
||||
'title' => $title,
|
||||
'description' => $description,
|
||||
'theme_supports' => 'custom-header',
|
||||
'priority' => 60,
|
||||
) );
|
||||
|
||||
$this->add_setting( 'header_video', array(
|
||||
'theme_supports' => array( 'custom-header', 'video' ),
|
||||
'transport' => 'postMessage',
|
||||
'sanitize_callback' => 'absint',
|
||||
'validate_callback' => array( $this, '_validate_header_video' ),
|
||||
) );
|
||||
|
||||
$this->add_setting( 'external_header_video', array(
|
||||
'theme_supports' => array( 'custom-header', 'video' ),
|
||||
'transport' => 'postMessage',
|
||||
'sanitize_callback' => 'esc_url',
|
||||
'validate_callback' => array( $this, '_validate_external_header_video' ),
|
||||
) );
|
||||
|
||||
$this->add_setting( new WP_Customize_Filter_Setting( $this, 'header_image', array(
|
||||
'default' => get_theme_support( 'custom-header', 'default-image' ),
|
||||
'theme_supports' => 'custom-header',
|
||||
|
@ -3265,8 +3310,30 @@ final class WP_Customize_Manager {
|
|||
'theme_supports' => 'custom-header',
|
||||
) ) );
|
||||
|
||||
$this->add_control( new WP_Customize_Media_Control( $this, 'header_video', array(
|
||||
'theme_supports' => array( 'custom-header', 'video' ),
|
||||
'label' => __( 'Header Video' ),
|
||||
'description' => $control_description,
|
||||
'section' => 'header_image',
|
||||
'mime_type' => 'video',
|
||||
) ) );
|
||||
|
||||
$this->add_control( 'external_header_video', array(
|
||||
'theme_supports' => array( 'custom-header', 'video' ),
|
||||
'type' => 'url',
|
||||
'description' => __( 'Or, enter a YouTube or Vimeo URL:' ),
|
||||
'section' => 'header_image',
|
||||
) );
|
||||
|
||||
$this->add_control( new WP_Customize_Header_Image_Control( $this ) );
|
||||
|
||||
$this->selective_refresh->add_partial( 'custom_header', array(
|
||||
'selector' => '#wp-custom-header',
|
||||
'render_callback' => 'the_custom_header_markup',
|
||||
'settings' => array( 'header_video', 'external_header_video', 'header_image' ), // The image is used as a video fallback here.
|
||||
'container_inclusive' => true,
|
||||
) );
|
||||
|
||||
/* Custom Background */
|
||||
|
||||
$this->add_section( 'background_image', array(
|
||||
|
@ -3704,6 +3771,71 @@ final class WP_Customize_Manager {
|
|||
return $value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Export header video settings to facilitate selective refresh.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @param array $response Response.
|
||||
* @param WP_Customize_Selective_Refresh $selective_refresh Selective refresh component.
|
||||
* @param array $partials Array of partials.
|
||||
* @return array
|
||||
*/
|
||||
public function export_header_video_settings( $response, $selective_refresh, $partials ) {
|
||||
if ( isset( $partials['header_video'] ) || isset( $partials['external_header_video'] ) ) {
|
||||
$response['custom_header_settings'] = get_header_video_settings();
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for validating the header_video value.
|
||||
*
|
||||
* Ensures that the selected video is less than 8MB and provides an error message.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @param WP_Error $validity
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function _validate_header_video( $validity, $value ) {
|
||||
$video = get_attached_file( absint( $value ) );
|
||||
if ( $video ) {
|
||||
$size = filesize( $video );
|
||||
if ( 8 < $size / pow( 1024, 2 ) ) { // Check whether the size is larger than 8MB.
|
||||
$validity->add( 'size_too_large', __( 'This video file is too large to use as a header video. Try a shorter video or optimize the compression settings and re-upload a file that is less than 8MB. Or, upload your video to YouTube and link it with the option below.' ) );
|
||||
}
|
||||
if ( '.mp4' !== substr( $video, -4 ) && '.mov' !== substr( $video, -4 ) ) { // Check for .mp4 or .mov format, which (assuming h.264 encoding) are the only cross-browser-supported formats.
|
||||
$validity->add( 'invalid_file_type', __( 'Only <code>.mp4</code> or <code>.mov</code> files may be used for header video. Please convert your video file and try again, or, upload your video to YouTube and link it with the option below.' ) );
|
||||
}
|
||||
}
|
||||
return $validity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for validating the external_header_video value.
|
||||
*
|
||||
* Ensures that the provided URL is for YouTube or Vimeo.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @param WP_Error $validity
|
||||
* @param mixed $value
|
||||
* @return mixed
|
||||
*/
|
||||
public function _validate_external_header_video( $validity, $value ) {
|
||||
$video = esc_url( $value );
|
||||
if ( $video ) {
|
||||
if ( ! preg_match( '#^https?://(?:www\.)?(?:youtube\.com/watch|youtu\.be/)#', $video )
|
||||
&& ! preg_match( '#^https?://(.+\.)?vimeo\.com/.*#', $video ) ) {
|
||||
$validity->add( 'invalid_url', __( 'Please enter a valid YouTube or Vimeo video URL.' ) );
|
||||
}
|
||||
}
|
||||
return $validity;
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback for rendering the custom logo, used in the custom_logo partial.
|
||||
*
|
||||
|
|
|
@ -166,9 +166,14 @@ class WP_Customize_Header_Image_Control extends WP_Customize_Image_Control {
|
|||
$height = absint( get_theme_support( 'custom-header', 'height' ) );
|
||||
?>
|
||||
<div class="customize-control-content">
|
||||
<p class="customizer-section-intro">
|
||||
<?php if ( current_theme_supports( 'custom-header', 'video' ) ) {
|
||||
echo '<span class="customize-control-title">' . $this->label . '</span>';
|
||||
} ?>
|
||||
<p class="customizer-section-intro customize-control-description">
|
||||
<?php
|
||||
if ( $width && $height ) {
|
||||
if ( current_theme_supports( 'custom-header', 'video' ) ) {
|
||||
_e( 'While you can crop images to your liking after clicking <strong>Add new image</strong>, we recommend matching the size of your video.' );
|
||||
} elseif ( $width && $height ) {
|
||||
/* translators: %s: header size in pixels */
|
||||
printf( __( 'While you can crop images to your liking after clicking <strong>Add new image</strong>, your theme recommends a header size of %s pixels.' ),
|
||||
sprintf( '<strong>%s × %s</strong>', $width, $height )
|
||||
|
|
|
@ -0,0 +1,149 @@
|
|||
(function( window, $, settings ) {
|
||||
|
||||
function wpCustomHeader() {
|
||||
var handlers = {
|
||||
nativeVideo: {
|
||||
test: function( settings ) {
|
||||
var video = document.createElement( 'video' );
|
||||
return video.canPlayType( settings.mimeType );
|
||||
},
|
||||
callback: nativeHandler
|
||||
},
|
||||
youtube: {
|
||||
test: function( settings ) {
|
||||
return 'video/x-youtube' === settings.mimeType;
|
||||
},
|
||||
callback: youtubeHandler
|
||||
}
|
||||
};
|
||||
|
||||
function initialize() {
|
||||
settings.container = document.getElementById( 'wp-custom-header' );
|
||||
|
||||
if ( supportsVideo() ) {
|
||||
for ( var id in handlers ) {
|
||||
var handler = handlers[ id ];
|
||||
|
||||
if ( handlers.hasOwnProperty( id ) && handler.test( settings ) ) {
|
||||
handler.callback( settings );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$( 'body' ).trigger( 'wp-custom-header-video-loaded' );
|
||||
}
|
||||
}
|
||||
|
||||
function supportsVideo() {
|
||||
// Don't load video on small screens. @todo: consider bandwidth and other factors.
|
||||
if ( window.innerWidth < settings.minWidth || window.innerHeight < settings.minHeight ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return {
|
||||
handlers: handlers,
|
||||
initialize: initialize,
|
||||
supportsVideo: supportsVideo
|
||||
};
|
||||
}
|
||||
|
||||
function nativeHandler( settings ) {
|
||||
var video = document.createElement( 'video' );
|
||||
|
||||
video.id = 'wp-custom-header-video';
|
||||
video.autoplay = 'autoplay';
|
||||
video.loop = 'loop';
|
||||
video.muted = 'muted';
|
||||
video.width = settings.width;
|
||||
video.height = settings.height;
|
||||
|
||||
video.addEventListener( 'click', function() {
|
||||
if ( video.paused ) {
|
||||
video.play();
|
||||
} else {
|
||||
video.pause();
|
||||
}
|
||||
});
|
||||
|
||||
settings.container.innerHTML = '';
|
||||
settings.container.appendChild( video );
|
||||
video.src = settings.videoUrl;
|
||||
}
|
||||
|
||||
function youtubeHandler( settings ) {
|
||||
// @link http://stackoverflow.com/a/27728417
|
||||
var VIDEO_ID_REGEX = /^.*(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/)|(?:(?:watch)?\?v(?:i)?=|\&v(?:i)?=))([^#\&\?]*).*/,
|
||||
videoId = settings.videoUrl.match( VIDEO_ID_REGEX )[1];
|
||||
|
||||
function loadVideo() {
|
||||
var YT = window.YT || {};
|
||||
|
||||
YT.ready(function() {
|
||||
var video = document.createElement( 'div' );
|
||||
video.id = 'wp-custom-header-video';
|
||||
settings.container.innerHTML = '';
|
||||
settings.container.appendChild( video );
|
||||
|
||||
new YT.Player( video, {
|
||||
height: settings.height,
|
||||
width: settings.width,
|
||||
videoId: videoId,
|
||||
events: {
|
||||
onReady: function( e ) {
|
||||
e.target.mute();
|
||||
},
|
||||
onStateChange: function( e ) {
|
||||
if ( YT.PlayerState.ENDED === e.data ) {
|
||||
e.target.playVideo();
|
||||
}
|
||||
}
|
||||
},
|
||||
playerVars: {
|
||||
autoplay: 1,
|
||||
controls: 0,
|
||||
disablekb: 1,
|
||||
fs: 0,
|
||||
iv_load_policy: 3,
|
||||
loop: 1,
|
||||
modestbranding: 1,
|
||||
//origin: '',
|
||||
playsinline: 1,
|
||||
rel: 0,
|
||||
showinfo: 0
|
||||
}
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
if ( 'YT' in window ) {
|
||||
loadVideo();
|
||||
} else {
|
||||
var tag = document.createElement( 'script' );
|
||||
tag.src = 'https://www.youtube.com/player_api';
|
||||
tag.onload = function () { loadVideo(); };
|
||||
document.getElementsByTagName( 'head' )[0].appendChild( tag );
|
||||
}
|
||||
}
|
||||
|
||||
window.wp = window.wp || {};
|
||||
window.wp.customHeader = new wpCustomHeader();
|
||||
document.addEventListener( 'DOMContentLoaded', window.wp.customHeader.initialize, false );
|
||||
|
||||
if ( 'customize' in window.wp ) {
|
||||
wp.customize.selectiveRefresh.bind( 'render-partials-response', function( response ) {
|
||||
if ( 'custom_header_settings' in response ) {
|
||||
settings = response.custom_header_settings;
|
||||
}
|
||||
});
|
||||
|
||||
wp.customize.selectiveRefresh.bind( 'partial-content-rendered', function( placement ) {
|
||||
if ( 'custom_header' === placement.partial.id ) {
|
||||
window.wp.customHeader.initialize();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
})( window, jQuery, window._wpCustomHeaderSettings || {} );
|
|
@ -0,0 +1 @@
|
|||
!function(a,b,c){function d(){function d(){if(c.container=document.getElementById("wp-custom-header"),g()){for(var a in h){var d=h[a];if(h.hasOwnProperty(a)&&d.test(c)){d.callback(c);break}}b("body").trigger("wp-custom-header-video-loaded")}}function g(){return!(a.innerWidth<c.minWidth||a.innerHeight<c.minHeight)}var h={nativeVideo:{test:function(a){var b=document.createElement("video");return b.canPlayType(a.mimeType)},callback:e},youtube:{test:function(a){return"video/x-youtube"===a.mimeType},callback:f}};return{handlers:h,initialize:d,supportsVideo:g}}function e(a){var b=document.createElement("video");b.id="wp-custom-header-video",b.autoplay="autoplay",b.loop="loop",b.muted="muted",b.width=a.width,b.height=a.height,b.addEventListener("click",function(){b.paused?b.play():b.pause()}),a.container.innerHTML="",a.container.appendChild(b),b.src=a.videoUrl}function f(b){function c(){var c=a.YT||{};c.ready(function(){var a=document.createElement("div");a.id="wp-custom-header-video",b.container.innerHTML="",b.container.appendChild(a),new c.Player(a,{height:b.height,width:b.width,videoId:e,events:{onReady:function(a){a.target.mute()},onStateChange:function(a){c.PlayerState.ENDED===a.data&&a.target.playVideo()}},playerVars:{autoplay:1,controls:0,disablekb:1,fs:0,iv_load_policy:3,loop:1,modestbranding:1,playsinline:1,rel:0,showinfo:0}})})}var d=/^.*(?:(?:youtu\.be\/|v\/|vi\/|u\/\w\/|embed\/)|(?:(?:watch)?\?v(?:i)?=|\&v(?:i)?=))([^#\&\?]*).*/,e=b.videoUrl.match(d)[1];if("YT"in a)c();else{var f=document.createElement("script");f.src="https://www.youtube.com/player_api",f.onload=function(){c()},document.getElementsByTagName("head")[0].appendChild(f)}}a.wp=a.wp||{},a.wp.customHeader=new d,document.addEventListener("DOMContentLoaded",a.wp.customHeader.initialize,!1),"customize"in a.wp&&(wp.customize.selectiveRefresh.bind("render-partials-response",function(a){"custom_header_settings"in a&&(c=a.custom_header_settings)}),wp.customize.selectiveRefresh.bind("partial-content-rendered",function(b){"custom_header"===b.partial.id&&a.wp.customHeader.initialize()}))}(window,jQuery,window._wpCustomHeaderSettings||{});
|
|
@ -479,6 +479,8 @@ function wp_default_scripts( &$scripts ) {
|
|||
$scripts->add( 'customize-nav-menus', "/wp-admin/js/customize-nav-menus$suffix.js", array( 'jquery', 'wp-backbone', 'customize-controls', 'accordion', 'nav-menu' ), false, 1 );
|
||||
$scripts->add( 'customize-preview-nav-menus', "/wp-includes/js/customize-preview-nav-menus$suffix.js", array( 'jquery', 'wp-util', 'customize-preview', 'customize-selective-refresh' ), false, 1 );
|
||||
|
||||
$scripts->add( 'wp-custom-header', "/wp-includes/js/wp-custom-header$suffix.js", array(), false, 1 );
|
||||
|
||||
$scripts->add( 'accordion', "/wp-admin/js/accordion$suffix.js", array( 'jquery' ), false, 1 );
|
||||
|
||||
$scripts->add( 'shortcode', "/wp-includes/js/shortcode$suffix.js", array( 'underscore' ), false, 1 );
|
||||
|
|
|
@ -1264,6 +1264,7 @@ function get_custom_header() {
|
|||
'thumbnail_url' => '',
|
||||
'width' => get_theme_support( 'custom-header', 'width' ),
|
||||
'height' => get_theme_support( 'custom-header', 'height' ),
|
||||
'video' => get_theme_support( 'custom-header', 'video' ),
|
||||
);
|
||||
return (object) wp_parse_args( $data, $default );
|
||||
}
|
||||
|
@ -1310,6 +1311,138 @@ function unregister_default_headers( $header ) {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a header video is set or not.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @see get_header_video_url()
|
||||
*
|
||||
* @return bool Whether a header video is set or not.
|
||||
*/
|
||||
function has_header_video() {
|
||||
return (bool) get_header_video_url();
|
||||
}
|
||||
|
||||
/* Retrieve header video URL for custom header.
|
||||
*
|
||||
* Uses a local video if present, or falls back to an external video. Returns false if there is no video.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @return string|false
|
||||
*/
|
||||
function get_header_video_url() {
|
||||
$id = absint( get_theme_mod( 'header_video' ) );
|
||||
$url = esc_url( get_theme_mod( 'external_header_video' ) );
|
||||
|
||||
if ( ! $id && ! $url ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( $id ) {
|
||||
// Get the file URL from the attachment ID.
|
||||
$url = wp_get_attachment_url( $id );
|
||||
}
|
||||
|
||||
return esc_url_raw( set_url_scheme( $url ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Display header video URL.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*/
|
||||
function the_header_video_url() {
|
||||
$video = get_header_video_url();
|
||||
if ( $video ) {
|
||||
echo esc_url( $video );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve header video settings.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
function get_header_video_settings() {
|
||||
$header = get_custom_header();
|
||||
$video_url = get_header_video_url();
|
||||
$video_type = wp_check_filetype( $video_url, wp_get_mime_types() );
|
||||
|
||||
$settings = array(
|
||||
'mimeType' => '',
|
||||
'posterUrl' => get_header_image(),
|
||||
'videoUrl' => $video_url,
|
||||
'width' => absint( $header->width ),
|
||||
'height' => absint( $header->height ),
|
||||
'minWidth' => 900,
|
||||
'minHeight' => 500,
|
||||
);
|
||||
|
||||
if ( preg_match( '#^https?://(?:www\.)?(?:youtube\.com/watch|youtu\.be/)#', $video_url ) ) {
|
||||
$settings['mimeType'] = 'video/x-youtube';
|
||||
} elseif ( preg_match( '#^https?://(.+\.)?vimeo\.com/.*#', $video_url ) ) {
|
||||
$settings['mimeType'] = 'video/x-vimeo';
|
||||
} elseif ( ! empty( $video_type['type'] ) ) {
|
||||
$settings['mimeType'] = $video_type['type'];
|
||||
}
|
||||
|
||||
return apply_filters( 'header_video_settings', $settings );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a custom header is set or not.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @return bool True if a custom header is set. False if not.
|
||||
*/
|
||||
function has_custom_header() {
|
||||
if ( has_header_image() || ( is_front_page() && has_header_video() ) ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve the markup for a custom header.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*
|
||||
* @return string|false The markup for a custom header on success. False if not.
|
||||
*/
|
||||
function get_custom_header_markup() {
|
||||
if ( ! has_custom_header() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return sprintf(
|
||||
'<div id="wp-custom-header" class="wp-custom-header">%s</div>',
|
||||
get_header_image_tag()
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Print the markup for a custom header.
|
||||
*
|
||||
* @since 4.7.0
|
||||
*/
|
||||
function the_custom_header_markup() {
|
||||
if ( ! $custom_header = get_custom_header_markup() ) {
|
||||
return;
|
||||
}
|
||||
echo $custom_header;
|
||||
|
||||
if ( has_header_video() && is_front_page() ) {
|
||||
wp_enqueue_script( 'wp-custom-header' );
|
||||
wp_localize_script( 'wp-custom-header', '_wpCustomHeaderSettings', get_header_video_settings() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Retrieve background image for custom background.
|
||||
*
|
||||
|
@ -1732,6 +1865,7 @@ function add_theme_support( $feature ) {
|
|||
'wp-head-callback' => '',
|
||||
'admin-head-callback' => '',
|
||||
'admin-preview-callback' => '',
|
||||
'video' => false,
|
||||
);
|
||||
|
||||
$jit = isset( $args[0]['__jit'] );
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
*
|
||||
* @global string $wp_version
|
||||
*/
|
||||
$wp_version = '4.7-alpha-38984';
|
||||
$wp_version = '4.7-alpha-38985';
|
||||
|
||||
/**
|
||||
* Holds the WordPress DB revision, increments when changes are made to the WordPress DB schema.
|
||||
|
|
Loading…
Reference in New Issue