2008-02-21 07:00:15 +01:00
< ? php
2008-09-01 07:45:41 +02:00
/**
* WordPress API for media display .
*
* @ package WordPress
*/
2008-02-21 07:00:15 +01:00
2008-09-01 07:45:41 +02:00
/**
* Scale down the default size of an image .
*
* This is so that the image is a better fit for the editor and theme .
*
* The $size parameter accepts either an array or a string . The supported string
* values are 'thumb' or 'thumbnail' for the given thumbnail size or defaults at
* 128 width and 96 height in pixels . Also supported for the string value is
* 'medium' and 'full' . The 'full' isn ' t actually supported , but any value other
* than the supported will result in the content_width size or 500 if that is
* not set .
*
2011-09-30 00:57:43 +02:00
* Finally , there is a filter named 'editor_max_image_size' , that will be called
2008-09-01 07:45:41 +02:00
* on the calculated array for width and height , respectively . The second
* parameter will be the value that was in the $size parameter . The returned
* type for the hook is an array with the width as the first element and the
* height as the second element .
*
* @ since 2.5 . 0
* @ uses wp_constrain_dimensions () This function passes the widths and the heights .
*
* @ param int $width Width of the image
* @ param int $height Height of the image
* @ param string | array $size Size of what the result image should be .
* @ return array Width and height of what the result image should resize to .
*/
2008-02-21 07:00:15 +01:00
function image_constrain_size_for_editor ( $width , $height , $size = 'medium' ) {
2009-12-08 22:08:19 +01:00
global $content_width , $_wp_additional_image_sizes ;
2008-03-02 21:17:30 +01:00
2008-03-12 09:10:00 +01:00
if ( is_array ( $size ) ) {
$max_width = $size [ 0 ];
$max_height = $size [ 1 ];
}
elseif ( $size == 'thumb' || $size == 'thumbnail' ) {
2008-02-21 07:00:15 +01:00
$max_width = intval ( get_option ( 'thumbnail_size_w' ));
$max_height = intval ( get_option ( 'thumbnail_size_h' ));
// last chance thumbnail size defaults
if ( ! $max_width && ! $max_height ) {
$max_width = 128 ;
$max_height = 96 ;
}
}
elseif ( $size == 'medium' ) {
$max_width = intval ( get_option ( 'medium_size_w' ));
$max_height = intval ( get_option ( 'medium_size_h' ));
// if no width is set, default to the theme content width if available
}
2008-08-11 05:54:26 +02:00
elseif ( $size == 'large' ) {
2011-12-14 00:45:31 +01:00
// We're inserting a large size image into the editor. If it's a really
2008-09-18 08:14:46 +02:00
// big image we'll scale it down to fit reasonably within the editor
2011-12-14 00:45:31 +01:00
// itself, and within the theme's content width if it's known. The user
2008-09-18 08:14:46 +02:00
// can resize it in the editor if they wish.
2008-08-11 05:54:26 +02:00
$max_width = intval ( get_option ( 'large_size_w' ));
$max_height = intval ( get_option ( 'large_size_h' ));
if ( intval ( $content_width ) > 0 )
$max_width = min ( intval ( $content_width ), $max_width );
2009-12-08 22:08:19 +01:00
} elseif ( isset ( $_wp_additional_image_sizes ) && count ( $_wp_additional_image_sizes ) && in_array ( $size , array_keys ( $_wp_additional_image_sizes ) ) ) {
$max_width = intval ( $_wp_additional_image_sizes [ $size ][ 'width' ] );
$max_height = intval ( $_wp_additional_image_sizes [ $size ][ 'height' ] );
2010-02-14 07:34:47 +01:00
if ( intval ( $content_width ) > 0 && is_admin () ) // Only in admin. Assume that theme authors know what they're doing.
$max_width = min ( intval ( $content_width ), $max_width );
2008-08-11 05:54:26 +02:00
}
// $size == 'full' has no constraint
else {
$max_width = $width ;
$max_height = $height ;
2008-02-21 07:00:15 +01:00
}
list ( $max_width , $max_height ) = apply_filters ( 'editor_max_image_size' , array ( $max_width , $max_height ), $size );
2008-12-09 19:03:31 +01:00
2008-02-21 07:00:15 +01:00
return wp_constrain_dimensions ( $width , $height , $max_width , $max_height );
}
2008-09-01 07:45:41 +02:00
/**
* Retrieve width and height attributes using given width and height values .
*
* Both attributes are required in the sense that both parameters must have a
* value , but are optional in that if you set them to false or null , then they
* will not be added to the returned string .
*
* You can set the value using a string , but it will only take numeric values .
* If you wish to put 'px' after the numbers , then it will be stripped out of
* the return .
*
* @ since 2.5 . 0
*
* @ param int | string $width Optional . Width attribute value .
* @ param int | string $height Optional . Height attribute value .
* @ return string HTML attributes for width and , or height .
*/
2008-02-21 07:00:15 +01:00
function image_hwstring ( $width , $height ) {
$out = '' ;
if ( $width )
$out .= 'width="' . intval ( $width ) . '" ' ;
if ( $height )
$out .= 'height="' . intval ( $height ) . '" ' ;
return $out ;
}
2008-09-01 07:45:41 +02:00
/**
* Scale an image to fit a particular size ( such as 'thumb' or 'medium' ) .
*
* Array with image url , width , height , and whether is intermediate size , in
* that order is returned on success is returned . $is_intermediate is true if
* $url is a resized image , false if it is the original .
*
* The URL might be the original image , or it might be a resized version . This
* function won ' t create a new resized copy , it will just return an already
* resized one if it exists .
*
2008-09-18 08:14:46 +02:00
* A plugin may use the 'image_downsize' filter to hook into and offer image
* resizing services for images . The hook must return an array with the same
* elements that are returned in the function . The first element being the URL
* to the new image that was resized .
*
2008-09-01 07:45:41 +02:00
* @ since 2.5 . 0
* @ uses apply_filters () Calls 'image_downsize' on $id and $size to provide
2008-09-18 08:14:46 +02:00
* resize services .
2008-09-01 07:45:41 +02:00
*
* @ param int $id Attachment ID for image .
2011-03-23 19:46:38 +01:00
* @ param array | string $size Optional , default is 'medium' . Size of image , either array or string .
2008-09-01 07:45:41 +02:00
* @ return bool | array False on failure , array on success .
*/
2008-02-21 07:00:15 +01:00
function image_downsize ( $id , $size = 'medium' ) {
2008-03-02 21:17:30 +01:00
2008-03-10 22:31:33 +01:00
if ( ! wp_attachment_is_image ( $id ) )
return false ;
2008-02-21 07:00:15 +01:00
$img_url = wp_get_attachment_url ( $id );
$meta = wp_get_attachment_metadata ( $id );
$width = $height = 0 ;
2008-08-11 05:54:26 +02:00
$is_intermediate = false ;
2010-11-02 18:19:55 +01:00
$img_url_basename = wp_basename ( $img_url );
2008-03-02 21:17:30 +01:00
2008-02-21 07:00:15 +01:00
// plugins can use this to provide resize services
if ( $out = apply_filters ( 'image_downsize' , false , $id , $size ) )
return $out ;
2008-03-02 21:17:30 +01:00
2008-03-03 05:17:37 +01:00
// try for a new style intermediate size
if ( $intermediate = image_get_intermediate_size ( $id , $size ) ) {
2010-11-02 18:19:55 +01:00
$img_url = str_replace ( $img_url_basename , $intermediate [ 'file' ], $img_url );
2008-03-03 05:17:37 +01:00
$width = $intermediate [ 'width' ];
$height = $intermediate [ 'height' ];
2008-08-11 05:54:26 +02:00
$is_intermediate = true ;
2008-03-03 05:17:37 +01:00
}
elseif ( $size == 'thumbnail' ) {
// fall back to the old thumbnail
2008-07-04 18:15:29 +02:00
if ( ( $thumb_file = wp_get_attachment_thumb_file ( $id )) && $info = getimagesize ( $thumb_file ) ) {
2010-11-02 18:19:55 +01:00
$img_url = str_replace ( $img_url_basename , wp_basename ( $thumb_file ), $img_url );
2008-03-03 05:17:37 +01:00
$width = $info [ 0 ];
$height = $info [ 1 ];
2008-08-11 05:54:26 +02:00
$is_intermediate = true ;
2008-02-21 07:00:15 +01:00
}
}
2008-03-12 09:10:00 +01:00
if ( ! $width && ! $height && isset ( $meta [ 'width' ], $meta [ 'height' ]) ) {
2008-08-11 05:54:26 +02:00
// any other type: use the real image
$width = $meta [ 'width' ];
$height = $meta [ 'height' ];
2008-02-21 07:00:15 +01:00
}
2008-12-09 19:03:31 +01:00
2008-08-11 05:54:26 +02:00
if ( $img_url ) {
// we have the actual image size, but might need to further constrain it if content_width is narrower
list ( $width , $height ) = image_constrain_size_for_editor ( $width , $height , $size );
2008-03-02 21:17:30 +01:00
2008-08-11 05:54:26 +02:00
return array ( $img_url , $width , $height , $is_intermediate );
}
2008-03-13 00:15:31 +01:00
return false ;
2008-03-02 21:17:30 +01:00
2008-02-21 07:00:15 +01:00
}
2009-12-08 22:08:19 +01:00
/**
* Registers a new image size
2011-09-30 00:57:43 +02:00
*
* @ since 2.9 . 0
2009-12-08 22:08:19 +01:00
*/
2010-10-27 02:33:29 +02:00
function add_image_size ( $name , $width = 0 , $height = 0 , $crop = false ) {
2009-12-08 22:08:19 +01:00
global $_wp_additional_image_sizes ;
2010-10-27 02:33:29 +02:00
$_wp_additional_image_sizes [ $name ] = array ( 'width' => absint ( $width ), 'height' => absint ( $height ), 'crop' => ( bool ) $crop );
2009-12-08 22:08:19 +01:00
}
/**
2009-12-10 07:14:36 +01:00
* Registers an image size for the post thumbnail
2011-09-30 00:57:43 +02:00
*
* @ since 2.9 . 0
2009-12-08 22:08:19 +01:00
*/
2010-10-27 02:33:29 +02:00
function set_post_thumbnail_size ( $width = 0 , $height = 0 , $crop = false ) {
2009-12-10 07:14:36 +01:00
add_image_size ( 'post-thumbnail' , $width , $height , $crop );
2009-12-08 22:08:19 +01:00
}
2008-05-31 21:12:55 +02:00
/**
* An < img src /> tag for an image attachment , scaling it down if requested .
*
2008-09-18 08:14:46 +02:00
* The filter 'get_image_tag_class' allows for changing the class name for the
* image without having to use regular expressions on the HTML content . The
* parameters are : what WordPress will use for the class , the Attachment ID ,
* image align value , and the size the image should be .
*
* The second filter 'get_image_tag' has the HTML content , which can then be
* further manipulated by a plugin to change all attribute values and even HTML
* content .
2008-05-31 21:12:55 +02:00
*
2008-09-01 07:45:41 +02:00
* @ since 2.5 . 0
*
2008-05-31 21:12:55 +02:00
* @ uses apply_filters () The 'get_image_tag_class' filter is the IMG element
* class attribute .
* @ uses apply_filters () The 'get_image_tag' filter is the full IMG element with
* all attributes .
*
* @ param int $id Attachment ID .
* @ param string $alt Image Description for the alt attribute .
* @ param string $title Image Description for the title attribute .
* @ param string $align Part of the class name for aligning the image .
* @ param string $size Optional . Default is 'medium' .
* @ return string HTML IMG element for given image attachment
*/
2008-03-22 00:21:27 +01:00
function get_image_tag ( $id , $alt , $title , $align , $size = 'medium' ) {
2008-02-21 07:00:15 +01:00
list ( $img_src , $width , $height ) = image_downsize ( $id , $size );
$hwstring = image_hwstring ( $width , $height );
2009-05-05 21:43:53 +02:00
$class = 'align' . esc_attr ( $align ) . ' size-' . esc_attr ( $size ) . ' wp-image-' . $id ;
2008-05-31 21:12:55 +02:00
$class = apply_filters ( 'get_image_tag_class' , $class , $id , $align , $size );
2012-11-07 00:23:03 +01:00
$html = '<img src="' . esc_attr ( $img_src ) . '" alt="' . esc_attr ( $alt ) . '" ' . $hwstring . 'class="' . $class . '" />' ;
2008-02-21 07:00:15 +01:00
2008-04-25 19:58:38 +02:00
$html = apply_filters ( 'get_image_tag' , $html , $id , $alt , $title , $align , $size );
2008-02-21 07:00:15 +01:00
return $html ;
}
2008-09-18 08:14:46 +02:00
/**
2011-09-05 21:08:15 +02:00
* Calculates the new dimensions for a downsampled image .
2008-09-18 08:14:46 +02:00
*
2010-01-25 19:50:01 +01:00
* If either width or height are empty , no constraint is applied on
2008-09-18 08:14:46 +02:00
* that dimension .
*
* @ since 2.5 . 0
*
* @ param int $current_width Current width of the image .
* @ param int $current_height Current height of the image .
* @ param int $max_width Optional . Maximum wanted width .
* @ param int $max_height Optional . Maximum wanted height .
* @ return array First item is the width , the second item is the height .
*/
2008-02-26 19:46:03 +01:00
function wp_constrain_dimensions ( $current_width , $current_height , $max_width = 0 , $max_height = 0 ) {
if ( ! $max_width and ! $max_height )
return array ( $current_width , $current_height );
2008-03-02 21:17:30 +01:00
2008-02-26 19:46:03 +01:00
$width_ratio = $height_ratio = 1.0 ;
2010-05-27 22:41:36 +02:00
$did_width = $did_height = false ;
2008-03-02 21:17:30 +01:00
2010-05-27 22:37:42 +02:00
if ( $max_width > 0 && $current_width > 0 && $current_width > $max_width ) {
2008-02-26 19:46:03 +01:00
$width_ratio = $max_width / $current_width ;
2010-05-27 22:37:42 +02:00
$did_width = true ;
}
2008-03-02 21:17:30 +01:00
2010-05-27 22:37:42 +02:00
if ( $max_height > 0 && $current_height > 0 && $current_height > $max_height ) {
2008-02-26 19:46:03 +01:00
$height_ratio = $max_height / $current_height ;
2010-05-27 22:37:42 +02:00
$did_height = true ;
}
2008-03-02 21:17:30 +01:00
2010-05-27 22:37:42 +02:00
// Calculate the larger/smaller ratios
$smaller_ratio = min ( $width_ratio , $height_ratio );
$larger_ratio = max ( $width_ratio , $height_ratio );
if ( intval ( $current_width * $larger_ratio ) > $max_width || intval ( $current_height * $larger_ratio ) > $max_height )
// The larger ratio is too big. It would result in an overflow.
$ratio = $smaller_ratio ;
else
// The larger ratio fits, and is likely to be a more "snug" fit.
$ratio = $larger_ratio ;
$w = intval ( $current_width * $ratio );
$h = intval ( $current_height * $ratio );
// Sometimes, due to rounding, we'll end up with a result like this: 465x700 in a 177x177 box is 117x176... a pixel short
2011-09-05 21:08:15 +02:00
// We also have issues with recursive calls resulting in an ever-changing result. Constraining to the result of a constraint should yield the original result.
2010-05-27 22:37:42 +02:00
// Thus we look for dimensions that are one pixel shy of the max value and bump them up
2010-05-27 22:41:36 +02:00
if ( $did_width && $w == $max_width - 1 )
2010-05-27 22:37:42 +02:00
$w = $max_width ; // Round it up
2010-05-27 22:41:36 +02:00
if ( $did_height && $h == $max_height - 1 )
2010-05-27 22:37:42 +02:00
$h = $max_height ; // Round it up
return array ( $w , $h );
2008-02-26 19:46:03 +01:00
}
2008-09-18 08:14:46 +02:00
/**
* Retrieve calculated resized dimensions for use in imagecopyresampled () .
*
* Calculate dimensions and coordinates for a resized image that fits within a
* specified width and height . If $crop is true , the largest matching central
* portion of the image will be cropped out and resized to the required size .
*
* @ since 2.5 . 0
2012-05-02 22:15:44 +02:00
* @ uses apply_filters () Calls 'image_resize_dimensions' on $orig_w , $orig_h , $dest_w , $dest_h and
* $crop to provide custom resize dimensions .
2008-09-18 08:14:46 +02:00
*
* @ param int $orig_w Original width .
* @ param int $orig_h Original height .
* @ param int $dest_w New width .
* @ param int $dest_h New height .
* @ param bool $crop Optional , default is false . Whether to crop image or resize .
2011-09-30 00:57:43 +02:00
* @ return bool | array False on failure . Returned array matches parameters for imagecopyresampled () PHP function .
2008-09-18 08:14:46 +02:00
*/
2009-11-26 07:58:21 +01:00
function image_resize_dimensions ( $orig_w , $orig_h , $dest_w , $dest_h , $crop = false ) {
2008-03-02 21:17:30 +01:00
2008-02-26 19:46:03 +01:00
if ( $orig_w <= 0 || $orig_h <= 0 )
return false ;
// at least one of dest_w or dest_h must be specific
if ( $dest_w <= 0 && $dest_h <= 0 )
return false ;
2008-03-02 21:17:30 +01:00
2012-05-02 22:15:44 +02:00
// plugins can use this to provide custom resize dimensions
$output = apply_filters ( 'image_resize_dimensions' , null , $orig_w , $orig_h , $dest_w , $dest_h , $crop );
if ( null !== $output )
return $output ;
2008-02-26 19:46:03 +01:00
if ( $crop ) {
// crop the largest possible portion of the original image that we can size to $dest_w x $dest_h
$aspect_ratio = $orig_w / $orig_h ;
$new_w = min ( $dest_w , $orig_w );
$new_h = min ( $dest_h , $orig_h );
2009-11-26 07:58:21 +01:00
if ( ! $new_w ) {
2008-02-26 19:46:03 +01:00
$new_w = intval ( $new_h * $aspect_ratio );
}
2009-11-26 07:58:21 +01:00
if ( ! $new_h ) {
2008-02-26 19:46:03 +01:00
$new_h = intval ( $new_w / $aspect_ratio );
}
$size_ratio = max ( $new_w / $orig_w , $new_h / $orig_h );
2008-03-02 21:17:30 +01:00
2009-11-26 07:58:21 +01:00
$crop_w = round ( $new_w / $size_ratio );
$crop_h = round ( $new_h / $size_ratio );
2008-02-26 19:46:03 +01:00
2009-11-26 07:58:21 +01:00
$s_x = floor ( ( $orig_w - $crop_w ) / 2 );
$s_y = floor ( ( $orig_h - $crop_h ) / 2 );
} else {
2008-02-26 19:46:03 +01:00
// don't crop, just resize using $dest_w x $dest_h as a maximum bounding box
$crop_w = $orig_w ;
$crop_h = $orig_h ;
2008-03-02 21:17:30 +01:00
2008-02-26 19:46:03 +01:00
$s_x = 0 ;
$s_y = 0 ;
2008-03-02 21:17:30 +01:00
2008-02-26 19:46:03 +01:00
list ( $new_w , $new_h ) = wp_constrain_dimensions ( $orig_w , $orig_h , $dest_w , $dest_h );
}
2008-03-02 21:17:30 +01:00
2008-02-26 19:46:03 +01:00
// if the resulting image would be the same size or larger we don't want to resize it
2009-11-26 07:58:21 +01:00
if ( $new_w >= $orig_w && $new_h >= $orig_h )
2008-02-26 19:46:03 +01:00
return false ;
// the return array matches the parameters to imagecopyresampled()
// int dst_x, int dst_y, int src_x, int src_y, int dst_w, int dst_h, int src_w, int src_h
2009-12-12 09:06:24 +01:00
return array ( 0 , 0 , ( int ) $s_x , ( int ) $s_y , ( int ) $new_w , ( int ) $new_h , ( int ) $crop_w , ( int ) $crop_h );
2008-02-26 19:46:03 +01:00
}
2008-09-18 08:14:46 +02:00
/**
* Resize an image to make a thumbnail or intermediate size .
*
* The returned array has the file size , the image width , and image height . The
* filter 'image_make_intermediate_size' can be used to hook in and change the
* values of the returned array . The only parameter is the resized file path .
*
* @ since 2.5 . 0
*
* @ param string $file File path .
* @ param int $width Image width .
* @ param int $height Image height .
* @ param bool $crop Optional , default is false . Whether to crop image to specified height and width or resize .
* @ return bool | array False , if no image was created . Metadata array on success .
*/
2012-10-01 22:59:06 +02:00
function image_make_intermediate_size ( $file , $width , $height , $crop = false ) {
2008-03-03 05:17:37 +01:00
if ( $width || $height ) {
2012-10-01 22:59:06 +02:00
$editor = WP_Image_Editor :: get_instance ( $file );
2012-10-13 08:46:17 +02:00
if ( is_wp_error ( $editor ) || is_wp_error ( $editor -> resize ( $width , $height , $crop ) ) )
2012-10-01 22:59:06 +02:00
return false ;
$resized_file = $editor -> save ();
if ( ! is_wp_error ( $resized_file ) && $resized_file ) {
unset ( $resized_file [ 'path' ] );
return $resized_file ;
2008-03-03 05:17:37 +01:00
}
}
return false ;
}
2008-09-18 08:14:46 +02:00
/**
* Retrieve the image ' s intermediate size ( resized ) path , width , and height .
*
* The $size parameter can be an array with the width and height respectively .
* If the size matches the 'sizes' metadata array for width and height , then it
* will be used . If there is no direct match , then the nearest image size larger
* than the specified size will be used . If nothing is found , then the function
* will break out and return false .
2008-12-09 19:03:31 +01:00
*
2008-09-18 08:14:46 +02:00
* The metadata 'sizes' is used for compatible sizes that can be used for the
* parameter $size value .
*
* The url path will be given , when the $size parameter is a string .
*
2010-05-27 07:03:46 +02:00
* If you are passing an array for the $size , you should consider using
* add_image_size () so that a cropped version is generated . It ' s much more
* efficient than having to find the closest - sized image and then having the
* browser scale down the image .
*
2008-09-18 08:14:46 +02:00
* @ since 2.5 . 0
2010-05-27 07:03:46 +02:00
* @ see add_image_size ()
2008-09-18 08:14:46 +02:00
*
* @ param int $post_id Attachment ID for image .
* @ param array | string $size Optional , default is 'thumbnail' . Size of image , either array or string .
* @ return bool | array False on failure or array of file path , width , and height on success .
*/
2008-03-03 05:17:37 +01:00
function image_get_intermediate_size ( $post_id , $size = 'thumbnail' ) {
2008-07-06 18:40:15 +02:00
if ( ! is_array ( $imagedata = wp_get_attachment_metadata ( $post_id ) ) )
2008-03-03 05:17:37 +01:00
return false ;
2008-03-12 09:10:00 +01:00
// get the best one for a specified set of dimensions
if ( is_array ( $size ) && ! empty ( $imagedata [ 'sizes' ]) ) {
foreach ( $imagedata [ 'sizes' ] as $_size => $data ) {
// already cropped to width or height; so use this size
if ( ( $data [ 'width' ] == $size [ 0 ] && $data [ 'height' ] <= $size [ 1 ] ) || ( $data [ 'height' ] == $size [ 1 ] && $data [ 'width' ] <= $size [ 0 ] ) ) {
$file = $data [ 'file' ];
list ( $width , $height ) = image_constrain_size_for_editor ( $data [ 'width' ], $data [ 'height' ], $size );
return compact ( 'file' , 'width' , 'height' );
}
// add to lookup table: area => size
$areas [ $data [ 'width' ] * $data [ 'height' ]] = $_size ;
}
if ( ! $size || ! empty ( $areas ) ) {
// find for the smallest image not smaller than the desired size
ksort ( $areas );
foreach ( $areas as $_size ) {
$data = $imagedata [ 'sizes' ][ $_size ];
if ( $data [ 'width' ] >= $size [ 0 ] || $data [ 'height' ] >= $size [ 1 ] ) {
2010-02-14 09:21:07 +01:00
// Skip images with unexpectedly divergent aspect ratios (crops)
// First, we calculate what size the original image would be if constrained to a box the size of the current image in the loop
$maybe_cropped = image_resize_dimensions ( $imagedata [ 'width' ], $imagedata [ 'height' ], $data [ 'width' ], $data [ 'height' ], false );
2010-05-27 22:37:42 +02:00
// If the size doesn't match within one pixel, then it is of a different aspect ratio, so we skip it, unless it's the thumbnail size
if ( 'thumbnail' != $_size && ( ! $maybe_cropped || ( $maybe_cropped [ 4 ] != $data [ 'width' ] && $maybe_cropped [ 4 ] + 1 != $data [ 'width' ] ) || ( $maybe_cropped [ 5 ] != $data [ 'height' ] && $maybe_cropped [ 5 ] + 1 != $data [ 'height' ] ) ) )
2010-02-14 09:21:07 +01:00
continue ;
// If we're still here, then we're going to use this size
2008-03-12 09:10:00 +01:00
$file = $data [ 'file' ];
list ( $width , $height ) = image_constrain_size_for_editor ( $data [ 'width' ], $data [ 'height' ], $size );
return compact ( 'file' , 'width' , 'height' );
}
}
}
}
if ( is_array ( $size ) || empty ( $size ) || empty ( $imagedata [ 'sizes' ][ $size ]) )
2008-03-03 05:17:37 +01:00
return false ;
2008-08-09 07:36:14 +02:00
2008-03-13 00:15:31 +01:00
$data = $imagedata [ 'sizes' ][ $size ];
// include the full filesystem path of the intermediate file
if ( empty ( $data [ 'path' ]) && ! empty ( $data [ 'file' ]) ) {
$file_url = wp_get_attachment_url ( $post_id );
$data [ 'path' ] = path_join ( dirname ( $imagedata [ 'file' ]), $data [ 'file' ] );
$data [ 'url' ] = path_join ( dirname ( $file_url ), $data [ 'file' ] );
}
return $data ;
2008-03-03 05:17:37 +01:00
}
2010-01-08 09:51:12 +01:00
/**
* Get the available image sizes
2010-03-26 20:13:36 +01:00
* @ since 3.0 . 0
2010-01-08 09:51:12 +01:00
* @ return array Returns a filtered array of image size strings
*/
function get_intermediate_image_sizes () {
global $_wp_additional_image_sizes ;
$image_sizes = array ( 'thumbnail' , 'medium' , 'large' ); // Standard sizes
if ( isset ( $_wp_additional_image_sizes ) && count ( $_wp_additional_image_sizes ) )
$image_sizes = array_merge ( $image_sizes , array_keys ( $_wp_additional_image_sizes ) );
return apply_filters ( 'intermediate_image_sizes' , $image_sizes );
}
2008-09-18 08:14:46 +02:00
/**
* Retrieve an image to represent an attachment .
*
* A mime icon for files , thumbnail or intermediate size for images .
*
* @ since 2.5 . 0
*
* @ param int $attachment_id Image attachment ID .
* @ param string $size Optional , default is 'thumbnail' .
* @ param bool $icon Optional , default is false . Whether it is an icon .
* @ return bool | array Returns an array ( url , width , height ), or false , if no image is available .
*/
2008-03-12 09:10:00 +01:00
function wp_get_attachment_image_src ( $attachment_id , $size = 'thumbnail' , $icon = false ) {
2008-08-09 07:36:14 +02:00
2008-03-04 05:21:37 +01:00
// get a thumbnail or intermediate image if there is one
2008-03-10 22:31:33 +01:00
if ( $image = image_downsize ( $attachment_id , $size ) )
return $image ;
2009-06-06 17:02:55 +02:00
$src = false ;
2008-03-12 09:10:00 +01:00
if ( $icon && $src = wp_mime_type_icon ( $attachment_id ) ) {
2008-11-14 19:32:10 +01:00
$icon_dir = apply_filters ( 'icon_dir' , ABSPATH . WPINC . '/images/crystal' );
2010-11-02 18:19:55 +01:00
$src_file = $icon_dir . '/' . wp_basename ( $src );
2008-03-04 05:21:37 +01:00
@ list ( $width , $height ) = getimagesize ( $src_file );
}
if ( $src && $width && $height )
return array ( $src , $width , $height );
return false ;
}
2008-09-18 08:14:46 +02:00
/**
2009-03-08 06:42:17 +01:00
* Get an HTML img element representing an image attachment
2008-09-18 08:14:46 +02:00
*
2010-05-27 07:03:46 +02:00
* While $size will accept an array , it is better to register a size with
* add_image_size () so that a cropped version is generated . It ' s much more
* efficient than having to find the closest - sized image and then having the
* browser scale down the image .
*
* @ see add_image_size ()
2009-03-08 06:42:17 +01:00
* @ uses apply_filters () Calls 'wp_get_attachment_image_attributes' hook on attributes array
* @ uses wp_get_attachment_image_src () Gets attachment file URL and dimensions
2008-09-18 08:14:46 +02:00
* @ since 2.5 . 0
*
* @ param int $attachment_id Image attachment ID .
* @ param string $size Optional , default is 'thumbnail' .
* @ param bool $icon Optional , default is false . Whether it is an icon .
* @ return string HTML img element or empty string on failure .
*/
2009-10-15 14:31:48 +02:00
function wp_get_attachment_image ( $attachment_id , $size = 'thumbnail' , $icon = false , $attr = '' ) {
2008-03-04 05:21:37 +01:00
$html = '' ;
2008-03-12 09:10:00 +01:00
$image = wp_get_attachment_image_src ( $attachment_id , $size , $icon );
2008-03-04 05:21:37 +01:00
if ( $image ) {
list ( $src , $width , $height ) = $image ;
2008-11-26 03:27:37 +01:00
$hwstring = image_hwstring ( $width , $height );
2008-03-12 09:10:00 +01:00
if ( is_array ( $size ) )
$size = join ( 'x' , $size );
2012-08-23 22:01:10 +02:00
$attachment = get_post ( $attachment_id );
2009-10-15 14:31:48 +02:00
$default_attr = array (
2009-03-08 06:42:17 +01:00
'src' => $src ,
'class' => " attachment- $size " ,
2010-04-18 10:52:18 +02:00
'alt' => trim ( strip_tags ( get_post_meta ( $attachment_id , '_wp_attachment_image_alt' , true ) )), // Use Alt field first
2009-10-15 14:31:48 +02:00
);
2010-04-18 10:52:18 +02:00
if ( empty ( $default_attr [ 'alt' ]) )
$default_attr [ 'alt' ] = trim ( strip_tags ( $attachment -> post_excerpt )); // If not, Use the Caption
if ( empty ( $default_attr [ 'alt' ]) )
$default_attr [ 'alt' ] = trim ( strip_tags ( $attachment -> post_title )); // Finally, use the title
2009-10-15 14:31:48 +02:00
$attr = wp_parse_args ( $attr , $default_attr );
2009-03-08 06:42:17 +01:00
$attr = apply_filters ( 'wp_get_attachment_image_attributes' , $attr , $attachment );
2009-05-05 21:43:53 +02:00
$attr = array_map ( 'esc_attr' , $attr );
2009-03-08 06:42:17 +01:00
$html = rtrim ( " <img $hwstring " );
foreach ( $attr as $name => $value ) {
$html .= " $name = " . '"' . $value . '"' ;
}
$html .= ' />' ;
2008-03-04 05:21:37 +01:00
}
2008-08-09 07:36:14 +02:00
2008-03-04 05:21:37 +01:00
return $html ;
}
2008-03-03 05:17:37 +01:00
2009-10-15 16:27:04 +02:00
/**
2011-09-30 00:57:43 +02:00
* Adds a 'wp-post-image' class to post thumbnails
2009-12-10 07:14:36 +01:00
* Uses the begin_fetch_post_thumbnail_html and end_fetch_post_thumbnail_html action hooks to
2011-09-30 00:57:43 +02:00
* dynamically add / remove itself so as to only filter post thumbnails
2009-10-15 22:26:21 +02:00
*
2009-10-15 16:27:04 +02:00
* @ since 2.9 . 0
* @ param array $attr Attributes including src , class , alt , title
* @ return array
*/
2009-12-10 07:14:36 +01:00
function _wp_post_thumbnail_class_filter ( $attr ) {
2009-10-15 16:27:04 +02:00
$attr [ 'class' ] .= ' wp-post-image' ;
return $attr ;
}
/**
2009-12-10 07:14:36 +01:00
* Adds _wp_post_thumbnail_class_filter to the wp_get_attachment_image_attributes filter
2009-10-15 22:26:21 +02:00
*
2009-10-15 16:27:04 +02:00
* @ since 2.9 . 0
*/
2009-12-10 07:14:36 +01:00
function _wp_post_thumbnail_class_filter_add ( $attr ) {
add_filter ( 'wp_get_attachment_image_attributes' , '_wp_post_thumbnail_class_filter' );
2009-10-15 16:27:04 +02:00
}
/**
2009-12-10 07:14:36 +01:00
* Removes _wp_post_thumbnail_class_filter from the wp_get_attachment_image_attributes filter
2009-10-15 22:26:21 +02:00
*
2009-10-15 16:27:04 +02:00
* @ since 2.9 . 0
*/
2009-12-10 07:14:36 +01:00
function _wp_post_thumbnail_class_filter_remove ( $attr ) {
remove_filter ( 'wp_get_attachment_image_attributes' , '_wp_post_thumbnail_class_filter' );
2009-10-15 16:27:04 +02:00
}
2008-07-09 01:37:56 +02:00
add_shortcode ( 'wp_caption' , 'img_caption_shortcode' );
2008-07-11 17:59:14 +02:00
add_shortcode ( 'caption' , 'img_caption_shortcode' );
2008-07-02 20:41:11 +02:00
2008-09-18 08:14:46 +02:00
/**
* The Caption shortcode .
*
* Allows a plugin to replace the content that would otherwise be returned . The
* filter is 'img_caption_shortcode' and passes an empty string , the attr
* parameter and the content parameter values .
*
* The supported attributes for the shortcode are 'id' , 'align' , 'width' , and
* 'caption' .
*
* @ since 2.6 . 0
*
* @ param array $attr Attributes attributed to the shortcode .
* @ param string $content Optional . Shortcode content .
* @ return string
*/
2008-07-09 01:37:56 +02:00
function img_caption_shortcode ( $attr , $content = null ) {
2012-05-02 03:14:52 +02:00
// New-style shortcode with the caption inside the shortcode with the link and image tags.
if ( ! isset ( $attr [ 'caption' ] ) ) {
if ( preg_match ( '#((?:<a [^>]+>\s*)?<img [^>]+>(?:\s*</a>)?)(.*)#is' , $content , $matches ) ) {
$content = $matches [ 1 ];
$attr [ 'caption' ] = trim ( $matches [ 2 ] );
}
}
2008-07-11 17:59:14 +02:00
2008-07-02 20:41:11 +02:00
// Allow plugins/themes to override the default caption template.
2008-07-09 01:37:56 +02:00
$output = apply_filters ( 'img_caption_shortcode' , '' , $attr , $content );
2008-07-02 20:41:11 +02:00
if ( $output != '' )
return $output ;
extract ( shortcode_atts ( array (
'id' => '' ,
'align' => 'alignnone' ,
'width' => '' ,
'caption' => ''
), $attr ));
2008-08-09 07:36:14 +02:00
2008-07-02 20:41:11 +02:00
if ( 1 > ( int ) $width || empty ( $caption ) )
return $content ;
2008-08-09 07:36:14 +02:00
2009-08-18 18:05:07 +02:00
if ( $id ) $id = 'id="' . esc_attr ( $id ) . '" ' ;
2008-08-09 07:36:14 +02:00
2009-08-18 18:05:07 +02:00
return '<div ' . $id . 'class="wp-caption ' . esc_attr ( $align ) . '" style="width: ' . ( 10 + ( int ) $width ) . 'px">'
2009-02-04 18:07:26 +01:00
. do_shortcode ( $content ) . '<p class="wp-caption-text">' . $caption . '</p></div>' ;
2008-07-02 20:41:11 +02:00
}
2008-04-25 02:43:44 +02:00
add_shortcode ( 'gallery' , 'gallery_shortcode' );
2008-03-06 20:48:54 +01:00
2008-09-18 08:14:46 +02:00
/**
* The Gallery shortcode .
*
* This implements the functionality of the Gallery Shortcode for displaying
* WordPress images on a post .
*
* @ since 2.5 . 0
*
2011-09-30 00:57:43 +02:00
* @ param array $attr Attributes of the shortcode .
2008-09-18 08:14:46 +02:00
* @ return string HTML content to display gallery .
*/
2008-03-06 20:48:54 +01:00
function gallery_shortcode ( $attr ) {
2012-09-04 18:29:28 +02:00
$post = get_post ();
2009-05-25 01:47:49 +02:00
2009-05-15 10:52:04 +02:00
static $instance = 0 ;
$instance ++ ;
2008-03-06 20:48:54 +01:00
// Allow plugins/themes to override the default gallery template.
$output = apply_filters ( 'post_gallery' , '' , $attr );
if ( $output != '' )
return $output ;
2008-04-03 05:05:49 +02:00
// We're trusting author input, so let's at least make sure it looks like a valid orderby statement
if ( isset ( $attr [ 'orderby' ] ) ) {
$attr [ 'orderby' ] = sanitize_sql_orderby ( $attr [ 'orderby' ] );
if ( ! $attr [ 'orderby' ] )
unset ( $attr [ 'orderby' ] );
}
2008-03-24 03:57:19 +01:00
extract ( shortcode_atts ( array (
2008-05-05 17:46:32 +02:00
'order' => 'ASC' ,
'orderby' => 'menu_order ID' ,
2008-03-24 03:57:19 +01:00
'id' => $post -> ID ,
'itemtag' => 'dl' ,
'icontag' => 'dt' ,
'captiontag' => 'dd' ,
'columns' => 3 ,
2009-08-04 09:32:18 +02:00
'size' => 'thumbnail' ,
2012-09-06 21:19:56 +02:00
'ids' => '' ,
2009-08-04 09:32:18 +02:00
'include' => '' ,
'exclude' => ''
2008-03-24 03:57:19 +01:00
), $attr ));
$id = intval ( $id );
2009-08-04 09:32:18 +02:00
if ( 'RAND' == $order )
$orderby = 'none' ;
2012-09-06 21:19:56 +02:00
if ( ! empty ( $ids ) ) {
// 'ids' is explicitly ordered
$orderby = 'post__in' ;
$include = $ids ;
}
2009-08-04 09:32:18 +02:00
if ( ! empty ( $include ) ) {
$_attachments = get_posts ( array ( 'include' => $include , 'post_status' => 'inherit' , 'post_type' => 'attachment' , 'post_mime_type' => 'image' , 'order' => $order , 'orderby' => $orderby ) );
$attachments = array ();
foreach ( $_attachments as $key => $val ) {
$attachments [ $val -> ID ] = $_attachments [ $key ];
}
} elseif ( ! empty ( $exclude ) ) {
$attachments = get_children ( array ( 'post_parent' => $id , 'exclude' => $exclude , 'post_status' => 'inherit' , 'post_type' => 'attachment' , 'post_mime_type' => 'image' , 'order' => $order , 'orderby' => $orderby ) );
} else {
$attachments = get_children ( array ( 'post_parent' => $id , 'post_status' => 'inherit' , 'post_type' => 'attachment' , 'post_mime_type' => 'image' , 'order' => $order , 'orderby' => $orderby ) );
}
2008-03-06 20:48:54 +01:00
if ( empty ( $attachments ) )
return '' ;
2008-03-14 20:23:56 +01:00
if ( is_feed () ) {
$output = " \n " ;
2009-05-15 10:52:04 +02:00
foreach ( $attachments as $att_id => $attachment )
$output .= wp_get_attachment_link ( $att_id , $size , true ) . " \n " ;
2008-03-14 20:23:56 +01:00
return $output ;
}
2008-03-24 03:57:19 +01:00
$itemtag = tag_escape ( $itemtag );
$captiontag = tag_escape ( $captiontag );
$columns = intval ( $columns );
2008-03-26 04:34:55 +01:00
$itemwidth = $columns > 0 ? floor ( 100 / $columns ) : 100 ;
2010-05-03 07:49:19 +02:00
$float = is_rtl () ? 'right' : 'left' ;
2010-01-15 23:11:12 +01:00
2009-05-15 10:52:04 +02:00
$selector = " gallery- { $instance } " ;
2008-08-09 07:36:14 +02:00
2010-12-10 20:15:37 +01:00
$gallery_style = $gallery_div = '' ;
if ( apply_filters ( 'use_default_gallery_style' , true ) )
$gallery_style = "
2008-03-06 20:48:54 +01:00
< style type = 'text/css' >
2009-05-15 10:52:04 +02:00
#{$selector} {
2008-03-06 20:48:54 +01:00
margin : auto ;
}
2009-05-15 10:52:04 +02:00
#{$selector} .gallery-item {
2009-12-08 13:45:32 +01:00
float : { $float };
2008-03-06 20:48:54 +01:00
margin - top : 10 px ;
text - align : center ;
2010-12-10 20:15:37 +01:00
width : { $itemwidth } % ;
}
2009-05-15 10:52:04 +02:00
#{$selector} img {
2008-03-06 20:48:54 +01:00
border : 2 px solid #cfcfcf;
}
2009-05-15 10:52:04 +02:00
#{$selector} .gallery-caption {
2008-03-24 03:57:19 +01:00
margin - left : 0 ;
}
2008-03-06 20:48:54 +01:00
</ style >
2010-12-10 20:15:37 +01:00
<!-- see gallery_shortcode () in wp - includes / media . php --> " ;
$size_class = sanitize_html_class ( $size );
$gallery_div = " <div id=' $selector ' class='gallery galleryid- { $id } gallery-columns- { $columns } gallery-size- { $size_class } '> " ;
$output = apply_filters ( 'gallery_style' , $gallery_style . " \n \t \t " . $gallery_div );
2008-03-06 20:48:54 +01:00
2008-10-22 20:45:09 +02:00
$i = 0 ;
2008-03-06 20:48:54 +01:00
foreach ( $attachments as $id => $attachment ) {
2008-11-26 03:27:37 +01:00
$link = isset ( $attr [ 'link' ]) && 'file' == $attr [ 'link' ] ? wp_get_attachment_link ( $id , $size , false , false ) : wp_get_attachment_link ( $id , $size , true , false );
2008-11-23 07:37:15 +01:00
2008-03-24 03:57:19 +01:00
$output .= " < { $itemtag } class='gallery-item'> " ;
2008-03-06 20:48:54 +01:00
$output .= "
2008-03-24 03:57:19 +01:00
< { $icontag } class = 'gallery-icon' >
2008-03-06 20:48:54 +01:00
$link
2008-03-24 03:57:19 +01:00
</ { $icontag } > " ;
if ( $captiontag && trim ( $attachment -> post_excerpt ) ) {
$output .= "
2010-12-10 20:05:50 +01:00
< { $captiontag } class = 'wp-caption-text gallery-caption' >
2009-05-15 01:15:28 +02:00
" . wptexturize( $attachment->post_excerpt ) . "
2008-03-24 03:57:19 +01:00
</ { $captiontag } > " ;
}
$output .= " </ { $itemtag } > " ;
if ( $columns > 0 && ++ $i % $columns == 0 )
2008-03-06 20:48:54 +01:00
$output .= '<br style="clear: both" />' ;
}
$output .= "
2008-03-30 18:41:43 +02:00
< br style = 'clear: both;' />
2008-03-06 20:48:54 +01:00
</ div > \n " ;
return $output ;
}
2008-09-01 07:45:41 +02:00
/**
* Display previous image link that has the same post parent .
*
* @ since 2.5 . 0
2009-02-04 16:12:24 +01:00
* @ param string $size Optional , default is 'thumbnail' . Size of image , either array or string . 0 or 'none' will default to post_title or $text ;
* @ param string $text Optional , default is false . If included , link will reflect $text variable .
* @ return string HTML content .
2008-09-01 07:45:41 +02:00
*/
2009-02-04 16:12:24 +01:00
function previous_image_link ( $size = 'thumbnail' , $text = false ) {
adjacent_image_link ( true , $size , $text );
2008-03-11 01:09:14 +01:00
}
2008-09-01 07:45:41 +02:00
/**
* Display next image link that has the same post parent .
*
* @ since 2.5 . 0
2009-02-04 16:12:24 +01:00
* @ param string $size Optional , default is 'thumbnail' . Size of image , either array or string . 0 or 'none' will default to post_title or $text ;
* @ param string $text Optional , default is false . If included , link will reflect $text variable .
* @ return string HTML content .
2008-09-01 07:45:41 +02:00
*/
2009-02-04 16:12:24 +01:00
function next_image_link ( $size = 'thumbnail' , $text = false ) {
adjacent_image_link ( false , $size , $text );
2008-03-11 01:09:14 +01:00
}
2008-09-01 07:45:41 +02:00
/**
* Display next or previous image link that has the same post parent .
*
* Retrieves the current attachment object from the $post global .
*
* @ since 2.5 . 0
*
2011-09-30 00:57:43 +02:00
* @ param bool $prev Optional . Default is true to display previous link , false for next .
2008-09-01 07:45:41 +02:00
*/
2009-02-04 16:12:24 +01:00
function adjacent_image_link ( $prev = true , $size = 'thumbnail' , $text = false ) {
2012-09-04 18:29:28 +02:00
$post = get_post ();
$attachments = array_values ( get_children ( array ( 'post_parent' => $post -> post_parent , 'post_status' => 'inherit' , 'post_type' => 'attachment' , 'post_mime_type' => 'image' , 'order' => 'ASC' , 'orderby' => 'menu_order ID' ) ) );
2008-03-11 01:09:14 +01:00
foreach ( $attachments as $k => $attachment )
if ( $attachment -> ID == $post -> ID )
break ;
$k = $prev ? $k - 1 : $k + 1 ;
if ( isset ( $attachments [ $k ]) )
2009-02-04 16:12:24 +01:00
echo wp_get_attachment_link ( $attachments [ $k ] -> ID , $size , true , false , $text );
2008-03-11 01:09:14 +01:00
}
2008-09-18 08:14:46 +02:00
/**
* Retrieve taxonomies attached to the attachment .
*
* @ since 2.5 . 0
*
* @ param int | array | object $attachment Attachment ID , Attachment data array , or Attachment data object .
* @ return array Empty array on failure . List of taxonomies on success .
*/
2008-03-26 07:37:19 +01:00
function get_attachment_taxonomies ( $attachment ) {
if ( is_int ( $attachment ) )
$attachment = get_post ( $attachment );
else if ( is_array ( $attachment ) )
$attachment = ( object ) $attachment ;
if ( ! is_object ( $attachment ) )
return array ();
$filename = basename ( $attachment -> guid );
$objects = array ( 'attachment' );
if ( false !== strpos ( $filename , '.' ) )
$objects [] = 'attachment:' . substr ( $filename , strrpos ( $filename , '.' ) + 1 );
if ( ! empty ( $attachment -> post_mime_type ) ) {
$objects [] = 'attachment:' . $attachment -> post_mime_type ;
if ( false !== strpos ( $attachment -> post_mime_type , '/' ) )
foreach ( explode ( '/' , $attachment -> post_mime_type ) as $token )
if ( ! empty ( $token ) )
$objects [] = " attachment: $token " ;
}
$taxonomies = array ();
foreach ( $objects as $object )
if ( $taxes = get_object_taxonomies ( $object ) )
$taxonomies = array_merge ( $taxonomies , $taxes );
return array_unique ( $taxonomies );
}
2009-09-11 00:07:33 +02:00
2012-09-22 00:52:54 +02:00
/**
* Return all of the taxonomy names that are registered for attachments .
*
* Handles mime - type - specific taxonomies such as attachment : image and attachment : video .
*
* @ since 3.5 . 0
* @ see get_attachment_taxonomies ()
* @ uses get_taxonomies ()
*
* @ param string $output The type of output to return , either taxonomy 'names' or 'objects' . 'names' is the default .
* @ return array The names of all taxonomy of $object_type .
*/
function get_taxonomies_for_attachments ( $output = 'names' ) {
$taxonomies = array ();
foreach ( get_taxonomies ( array (), 'objects' ) as $taxonomy ) {
foreach ( $taxonomy -> object_type as $object_type ) {
if ( 'attachment' == $object_type || 0 === strpos ( $object_type , 'attachment:' ) ) {
if ( 'names' == $output )
$taxonomies [] = $taxonomy -> name ;
else
$taxonomies [ $taxonomy -> name ] = $taxonomy ;
break ;
}
}
}
return $taxonomies ;
}
2009-09-11 00:07:33 +02:00
/**
* Check if the installed version of GD supports particular image type
*
* @ since 2.9 . 0
*
2010-09-07 13:21:11 +02:00
* @ param string $mime_type
2009-09-11 00:07:33 +02:00
* @ return bool
*/
function gd_edit_image_support ( $mime_type ) {
if ( function_exists ( 'imagetypes' ) ) {
switch ( $mime_type ) {
case 'image/jpeg' :
return ( imagetypes () & IMG_JPG ) != 0 ;
case 'image/png' :
return ( imagetypes () & IMG_PNG ) != 0 ;
case 'image/gif' :
return ( imagetypes () & IMG_GIF ) != 0 ;
}
} else {
switch ( $mime_type ) {
case 'image/jpeg' :
return function_exists ( 'imagecreatefromjpeg' );
case 'image/png' :
return function_exists ( 'imagecreatefrompng' );
case 'image/gif' :
return function_exists ( 'imagecreatefromgif' );
2009-09-14 16:03:32 +02:00
}
2009-09-11 00:07:33 +02:00
}
return false ;
}
/**
* Create new GD image resource with transparency support
2012-10-01 22:59:06 +02:00
* @ TODO : Deprecate if possible .
2009-09-11 00:07:33 +02:00
*
* @ since 2.9 . 0
*
2010-09-07 13:21:11 +02:00
* @ param int $width Image width
* @ param int $height Image height
2009-09-11 00:07:33 +02:00
* @ return image resource
*/
function wp_imagecreatetruecolor ( $width , $height ) {
$img = imagecreatetruecolor ( $width , $height );
if ( is_resource ( $img ) && function_exists ( 'imagealphablending' ) && function_exists ( 'imagesavealpha' ) ) {
imagealphablending ( $img , false );
imagesavealpha ( $img , true );
}
return $img ;
}
2009-10-13 19:04:22 +02:00
/**
* Register an embed handler . This function should probably only be used for sites that do not support oEmbed .
*
2009-10-14 00:36:24 +02:00
* @ since 2.9 . 0
2009-10-13 19:04:22 +02:00
* @ see WP_Embed :: register_handler ()
*/
function wp_embed_register_handler ( $id , $regex , $callback , $priority = 10 ) {
global $wp_embed ;
$wp_embed -> register_handler ( $id , $regex , $callback , $priority );
}
/**
* Unregister a previously registered embed handler .
*
2009-10-14 00:36:24 +02:00
* @ since 2.9 . 0
2009-10-13 19:04:22 +02:00
* @ see WP_Embed :: unregister_handler ()
*/
function wp_embed_unregister_handler ( $id , $priority = 10 ) {
global $wp_embed ;
$wp_embed -> unregister_handler ( $id , $priority );
}
/**
* Create default array of embed parameters .
*
2012-09-25 09:10:09 +02:00
* The width defaults to the content width as specified by the theme . If the
* theme does not specify a content width , then 500 px is used .
*
* The default height is 1.5 times the width , or 1000 px , whichever is smaller .
*
* The 'embed_defaults' filter can be used to adjust either of these values .
*
2009-10-14 00:36:24 +02:00
* @ since 2.9 . 0
*
2009-10-13 19:04:22 +02:00
* @ return array Default embed parameters .
*/
function wp_embed_defaults () {
2012-09-25 09:10:09 +02:00
if ( ! empty ( $GLOBALS [ 'content_width' ] ) )
$width = ( int ) $GLOBALS [ 'content_width' ];
2009-10-13 19:04:22 +02:00
2012-09-25 09:10:09 +02:00
if ( empty ( $width ) )
2009-10-13 19:04:22 +02:00
$width = 500 ;
2012-09-25 09:10:09 +02:00
$height = min ( ceil ( $width * 1.5 ), 1000 );
2010-01-27 15:38:48 +01:00
2012-09-25 09:10:09 +02:00
return apply_filters ( 'embed_defaults' , compact ( 'width' , 'height' ) );
2009-10-13 19:04:22 +02:00
}
/**
* Based on a supplied width / height example , return the biggest possible dimensions based on the max width / height .
*
2009-10-14 00:36:24 +02:00
* @ since 2.9 . 0
2009-10-13 19:04:22 +02:00
* @ uses wp_constrain_dimensions () This function passes the widths and the heights .
*
* @ param int $example_width The width of an example embed .
* @ param int $example_height The height of an example embed .
* @ param int $max_width The maximum allowed width .
* @ param int $max_height The maximum allowed height .
* @ return array The maximum possible width and height based on the example ratio .
*/
function wp_expand_dimensions ( $example_width , $example_height , $max_width , $max_height ) {
$example_width = ( int ) $example_width ;
$example_height = ( int ) $example_height ;
$max_width = ( int ) $max_width ;
$max_height = ( int ) $max_height ;
return wp_constrain_dimensions ( $example_width * 1000000 , $example_height * 1000000 , $max_width , $max_height );
}
/**
* Attempts to fetch the embed HTML for a provided URL using oEmbed .
*
2009-10-14 00:36:24 +02:00
* @ since 2.9 . 0
2009-10-13 19:04:22 +02:00
* @ see WP_oEmbed
*
* @ uses _wp_oembed_get_object ()
* @ uses WP_oEmbed :: get_html ()
*
2011-09-05 21:08:15 +02:00
* @ param string $url The URL that should be embedded .
2011-09-30 00:57:43 +02:00
* @ param array $args Additional arguments and parameters .
2012-04-22 13:19:56 +02:00
* @ return bool | string False on failure or the embed HTML on success .
2009-10-13 19:04:22 +02:00
*/
function wp_oembed_get ( $url , $args = '' ) {
2010-04-18 11:51:19 +02:00
require_once ( ABSPATH . WPINC . '/class-oembed.php' );
2009-10-13 19:04:22 +02:00
$oembed = _wp_oembed_get_object ();
return $oembed -> get_html ( $url , $args );
}
2009-10-14 00:36:24 +02:00
/**
* Adds a URL format and oEmbed provider URL pair .
*
* @ since 2.9 . 0
* @ see WP_oEmbed
*
* @ uses _wp_oembed_get_object ()
*
2009-10-23 21:33:24 +02:00
* @ param string $format The format of URL that this provider can handle . You can use asterisks as wildcards .
2009-10-14 00:36:24 +02:00
* @ param string $provider The URL to the oEmbed provider .
2010-02-24 21:13:23 +01:00
* @ param boolean $regex Whether the $format parameter is in a regex format .
2009-10-14 00:36:24 +02:00
*/
2009-10-23 21:33:24 +02:00
function wp_oembed_add_provider ( $format , $provider , $regex = false ) {
2010-04-18 11:51:19 +02:00
require_once ( ABSPATH . WPINC . '/class-oembed.php' );
2009-10-14 00:36:24 +02:00
$oembed = _wp_oembed_get_object ();
2009-10-23 21:33:24 +02:00
$oembed -> providers [ $format ] = array ( $provider , $regex );
2011-04-28 19:03:23 +02:00
}
2012-07-26 22:18:27 +02:00
/**
* Removes an oEmbed provider .
*
* @ since 3.5
* @ see WP_oEmbed
*
* @ uses _wp_oembed_get_object ()
*
* @ param string $format The URL format for the oEmbed provider to remove .
*/
function wp_oembed_remove_provider ( $format ) {
require_once ( ABSPATH . WPINC . '/class-oembed.php' );
$oembed = _wp_oembed_get_object ();
if ( isset ( $oembed -> providers [ $format ] ) ) {
unset ( $oembed -> providers [ $format ] );
return true ;
}
return false ;
}
2011-04-28 19:03:23 +02:00
/**
* Determines if default embed handlers should be loaded .
*
* Checks to make sure that the embeds library hasn ' t already been loaded . If
* it hasn ' t , then it will load the embeds library .
*
* @ since 2.9 . 0
*/
function wp_maybe_load_embeds () {
if ( ! apply_filters ( 'load_default_embeds' , true ) )
return ;
wp_embed_register_handler ( 'googlevideo' , '#http://video\.google\.([A-Za-z.]{2,5})/videoplay\?docid=([\d-]+)(.*?)#i' , 'wp_embed_handler_googlevideo' );
}
/**
* The Google Video embed handler callback . Google Video does not support oEmbed .
*
* @ see WP_Embed :: register_handler ()
* @ see WP_Embed :: shortcode ()
*
* @ param array $matches The regex matches from the provided regex when calling { @ link wp_embed_register_handler ()} .
* @ param array $attr Embed attributes .
* @ param string $url The original URL that was matched by the regex .
* @ param array $rawattr The original unmodified attributes .
* @ return string The embed HTML .
*/
function wp_embed_handler_googlevideo ( $matches , $attr , $url , $rawattr ) {
// If the user supplied a fixed width AND height, use it
if ( ! empty ( $rawattr [ 'width' ]) && ! empty ( $rawattr [ 'height' ]) ) {
$width = ( int ) $rawattr [ 'width' ];
$height = ( int ) $rawattr [ 'height' ];
} else {
list ( $width , $height ) = wp_expand_dimensions ( 425 , 344 , $attr [ 'width' ], $attr [ 'height' ] );
}
return apply_filters ( 'embed_googlevideo' , '<embed type="application/x-shockwave-flash" src="http://video.google.com/googleplayer.swf?docid=' . esc_attr ( $matches [ 2 ]) . '&hl=en&fs=true" style="width:' . esc_attr ( $width ) . 'px;height:' . esc_attr ( $height ) . 'px" allowFullScreen="true" allowScriptAccess="always" />' , $matches , $attr , $url , $rawattr );
}
2012-03-15 05:14:05 +01:00
2012-09-27 22:59:57 +02:00
/**
* { @ internal Missing Short Description }}
*
* @ since 2.3 . 0
*
* @ param unknown_type $size
* @ return unknown
*/
function wp_convert_hr_to_bytes ( $size ) {
$size = strtolower ( $size );
$bytes = ( int ) $size ;
if ( strpos ( $size , 'k' ) !== false )
$bytes = intval ( $size ) * 1024 ;
elseif ( strpos ( $size , 'm' ) !== false )
$bytes = intval ( $size ) * 1024 * 1024 ;
elseif ( strpos ( $size , 'g' ) !== false )
$bytes = intval ( $size ) * 1024 * 1024 * 1024 ;
return $bytes ;
}
/**
* { @ internal Missing Short Description }}
*
* @ since 2.3 . 0
*
* @ param unknown_type $bytes
* @ return unknown
*/
function wp_convert_bytes_to_hr ( $bytes ) {
$units = array ( 0 => 'B' , 1 => 'kB' , 2 => 'MB' , 3 => 'GB' );
$log = log ( $bytes , 1024 );
$power = ( int ) $log ;
$size = pow ( 1024 , $log - $power );
return $size . $units [ $power ];
}
/**
* { @ internal Missing Short Description }}
*
* @ since 2.5 . 0
*
* @ return unknown
*/
function wp_max_upload_size () {
$u_bytes = wp_convert_hr_to_bytes ( ini_get ( 'upload_max_filesize' ) );
$p_bytes = wp_convert_hr_to_bytes ( ini_get ( 'post_max_size' ) );
$bytes = apply_filters ( 'upload_size_limit' , min ( $u_bytes , $p_bytes ), $u_bytes , $p_bytes );
return $bytes ;
}
2012-03-15 05:14:05 +01:00
/**
* Prints default plupload arguments .
*
* @ since 3.4 . 0
*/
function wp_plupload_default_settings () {
global $wp_scripts ;
2012-11-09 05:51:25 +01:00
$data = $wp_scripts -> get_data ( 'wp-plupload' , 'data' );
if ( $data && false !== strpos ( $data , '_wpPluploadSettings' ) )
return ;
2012-03-15 05:14:05 +01:00
$max_upload_size = wp_max_upload_size ();
2012-06-06 23:45:17 +02:00
$defaults = array (
2012-03-15 05:14:05 +01:00
'runtimes' => 'html5,silverlight,flash,html4' ,
'file_data_name' => 'async-upload' , // key passed to $_FILE.
'multiple_queues' => true ,
'max_file_size' => $max_upload_size . 'b' ,
2012-03-15 13:52:23 +01:00
'url' => admin_url ( 'admin-ajax.php' , 'relative' ),
2012-03-15 05:14:05 +01:00
'flash_swf_url' => includes_url ( 'js/plupload/plupload.flash.swf' ),
'silverlight_xap_url' => includes_url ( 'js/plupload/plupload.silverlight.xap' ),
'filters' => array ( array ( 'title' => __ ( 'Allowed Files' ), 'extensions' => '*' ) ),
'multipart' => true ,
'urlstream_upload' => true ,
);
2012-06-06 23:45:17 +02:00
$defaults = apply_filters ( 'plupload_default_settings' , $defaults );
2012-03-15 05:14:05 +01:00
2012-03-15 13:50:18 +01:00
$params = array (
'action' => 'upload-attachment' ,
);
$params = apply_filters ( 'plupload_default_params' , $params );
$params [ '_wpnonce' ] = wp_create_nonce ( 'media-form' );
2012-06-06 23:45:17 +02:00
$defaults [ 'multipart_params' ] = $params ;
$settings = array (
'defaults' => $defaults ,
'browser' => array (
'mobile' => wp_is_mobile (),
'supported' => _device_can_upload (),
),
);
2012-03-15 13:50:18 +01:00
2012-06-06 23:45:17 +02:00
$script = 'var _wpPluploadSettings = ' . json_encode ( $settings ) . ';' ;
2012-03-15 05:14:05 +01:00
if ( $data )
$script = " $data\n $script " ;
$wp_scripts -> add_data ( 'wp-plupload' , 'data' , $script );
}
2012-03-15 20:46:15 +01:00
add_action ( 'customize_controls_enqueue_scripts' , 'wp_plupload_default_settings' );
2012-08-31 04:04:40 +02:00
/**
* Prepares an attachment post object for JS , where it is expected
* to be JSON - encoded and fit into an Attachment model .
*
* @ since 3.5 . 0
*
* @ param mixed $attachment Attachment ID or object .
* @ return array Array of attachment details .
*/
function wp_prepare_attachment_for_js ( $attachment ) {
if ( ! $attachment = get_post ( $attachment ) )
return ;
if ( 'attachment' != $attachment -> post_type )
return ;
$meta = wp_get_attachment_metadata ( $attachment -> ID );
list ( $type , $subtype ) = explode ( '/' , $attachment -> post_mime_type );
$attachment_url = wp_get_attachment_url ( $attachment -> ID );
$response = array (
'id' => $attachment -> ID ,
'title' => $attachment -> post_title ,
'filename' => basename ( $attachment -> guid ),
'url' => $attachment_url ,
2012-10-10 23:54:21 +02:00
'link' => get_attachment_link ( $attachment -> ID ),
2012-08-31 04:04:40 +02:00
'alt' => get_post_meta ( $attachment -> ID , '_wp_attachment_image_alt' , true ),
'author' => $attachment -> post_author ,
'description' => $attachment -> post_content ,
'caption' => $attachment -> post_excerpt ,
'name' => $attachment -> post_name ,
'status' => $attachment -> post_status ,
'uploadedTo' => $attachment -> post_parent ,
2012-08-31 21:14:43 +02:00
'date' => strtotime ( $attachment -> post_date_gmt ) * 1000 ,
'modified' => strtotime ( $attachment -> post_modified_gmt ) * 1000 ,
2012-08-31 04:04:40 +02:00
'mime' => $attachment -> post_mime_type ,
'type' => $type ,
'subtype' => $subtype ,
2012-09-27 08:07:56 +02:00
'icon' => wp_mime_type_icon ( $attachment -> ID ),
2012-11-10 19:25:04 +01:00
'dateFormatted' => mysql2date ( get_option ( 'date_format' ), $attachment -> post_date ),
2012-08-31 04:04:40 +02:00
);
2012-09-06 11:50:41 +02:00
if ( $meta && 'image' === $type ) {
2012-08-31 04:04:40 +02:00
$sizes = array ();
$base_url = str_replace ( wp_basename ( $attachment_url ), '' , $attachment_url );
2012-09-06 11:50:41 +02:00
if ( isset ( $meta [ 'sizes' ] ) ) {
foreach ( $meta [ 'sizes' ] as $slug => $size ) {
$sizes [ $slug ] = array (
'height' => $size [ 'height' ],
'width' => $size [ 'width' ],
'url' => $base_url . $size [ 'file' ],
'orientation' => $size [ 'height' ] > $size [ 'width' ] ? 'portrait' : 'landscape' ,
);
}
2012-08-31 04:04:40 +02:00
}
2012-11-14 23:08:02 +01:00
$sizes [ 'full' ] = array (
2012-08-31 04:04:40 +02:00
'height' => $meta [ 'height' ],
'width' => $meta [ 'width' ],
2012-11-14 23:08:02 +01:00
'url' => $attachment_url ,
2012-08-31 04:04:40 +02:00
'orientation' => $meta [ 'height' ] > $meta [ 'width' ] ? 'portrait' : 'landscape' ,
2012-11-14 23:08:02 +01:00
);
$response = array_merge ( $response , array ( 'sizes' => $sizes ), $sizes [ 'full' ] );
2012-08-31 04:04:40 +02:00
}
2012-11-11 02:26:42 +01:00
if ( function_exists ( 'get_compat_media_markup' ) )
$response [ 'compat' ] = get_compat_media_markup ( $attachment -> ID );
2012-08-31 04:04:40 +02:00
return apply_filters ( 'wp_prepare_attachment_for_js' , $response , $attachment , $meta );
}
Add new media workflow scripts, styles, and templates.
Please note that this commit does not integrate media into the existing UI. If you would like to see the new UI, navigate to the post editor and run the following in your browser's Javascript console:
new wp.media.controller.Workflow().render().modal.open();
The Javascript is broken up into two files, with the slugs media-models and media-views.
* media-models: The models are UI agnostic, and can be used independent of the views. If you'd like to create custom UIs, this is the script for you.
* media-views: This is the Media Experience. The views (and controllers) depend on the models (which are listed as a dependency and will automatically be included thanks to wp_enqueue_script). The views also require the media templates, media-view styles, and the plupload bridge settings. Perhaps we should create a function to include the whole shebang, but in the meantime...
To include media-views in the admin, run the following PHP in or after 'admin_enqueue_scripts':
wp_enqueue_script( 'media-views' );
wp_enqueue_style( 'media-views' );
wp_plupload_default_settings();
add_action( 'admin_footer', 'wp_print_media_templates' );
see #21390.
git-svn-id: http://core.svn.wordpress.org/trunk@21683 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2012-08-31 06:54:23 +02:00
2012-11-09 05:57:25 +01:00
/**
* Enqueues all scripts , styles , settings , and templates necessary to use
* all media JS APIs .
*
* @ since 3.5 . 0
*/
2012-11-14 10:06:10 +01:00
function wp_enqueue_media ( $args = array () ) {
$defaults = array (
'post' => null ,
);
$args = wp_parse_args ( $args , $defaults );
2012-11-10 08:51:37 +01:00
// We're going to pass the old thickbox media tabs to `media_upload_tabs`
// to ensure plugins will work. We will then unset those tabs.
$tabs = array (
2012-11-10 08:56:17 +01:00
// handler action suffix => tab label
'type' => '' ,
'type_url' => '' ,
'gallery' => '' ,
'library' => '' ,
2012-11-10 08:51:37 +01:00
);
$tabs = apply_filters ( 'media_upload_tabs' , $tabs );
unset ( $tabs [ 'type' ], $tabs [ 'type_url' ], $tabs [ 'gallery' ], $tabs [ 'library' ] );
$settings = array (
'tabs' => $tabs ,
'tabUrl' => add_query_arg ( array (
'chromeless' => true
), admin_url ( 'media-upload.php' ) ),
);
2012-11-14 10:06:10 +01:00
if ( isset ( $args [ 'post' ] ) )
$settings [ 'postId' ] = get_post ( $args [ 'post' ] ) -> ID ;
2012-11-10 01:37:13 +01:00
wp_localize_script ( 'media-views' , '_wpMediaViewsL10n' , array (
2012-11-10 08:51:37 +01:00
// Settings
'settings' => $settings ,
2012-11-10 01:37:13 +01:00
// Generic
2012-11-12 06:57:12 +01:00
'url' => __ ( 'URL' ),
2012-11-10 01:37:13 +01:00
'insertMedia' => __ ( 'Insert Media' ),
'search' => __ ( 'Search' ),
'select' => __ ( 'Select' ),
'cancel' => __ ( 'Cancel' ),
'addImages' => __ ( 'Add images' ),
'selected' => __ ( 'selected' ),
2012-11-10 10:11:33 +01:00
'dragInfo' => __ ( 'Drag and drop to reorder images.' ),
2012-11-10 01:37:13 +01:00
// Upload
'uploadFilesTitle' => __ ( 'Upload Files' ),
'selectFiles' => __ ( 'Select files' ),
'uploadImagesTitle' => __ ( 'Upload Images' ),
2012-11-13 00:52:17 +01:00
'uploadMoreFiles' => __ ( 'Upload more files' ),
2012-11-10 01:37:13 +01:00
// Library
'mediaLibraryTitle' => __ ( 'Media Library' ),
'createNewGallery' => __ ( 'Create a new gallery' ),
'insertIntoPost' => __ ( 'Insert into post' ),
// Embed
'embedFromUrlTitle' => __ ( 'Embed From URL' ),
2012-11-12 06:57:12 +01:00
'insertEmbed' => __ ( 'Insert embed' ),
2012-11-10 01:37:13 +01:00
// Batch
'batchInsert' => __ ( 'Batch insert' ),
'cancelBatchTitle' => __ ( '← Cancel Batch' ),
'editBatchTitle' => __ ( 'Edit Batch' ),
'addToBatch' => __ ( 'Add to batch' ),
// Gallery
'createGalleryTitle' => __ ( 'Create Gallery' ),
'editGalleryTitle' => __ ( 'Edit Gallery' ),
'cancelGalleryTitle' => __ ( '← Cancel Gallery' ),
'insertGallery' => __ ( 'Insert gallery' ),
'updateGallery' => __ ( 'Update gallery' ),
'continueEditing' => __ ( 'Continue editing' ),
'addToGallery' => __ ( 'Add to gallery' ),
) );
2012-11-09 05:57:25 +01:00
wp_enqueue_script ( 'media-upload' );
wp_enqueue_style ( 'media-views' );
wp_plupload_default_settings ();
add_action ( 'admin_footer' , 'wp_print_media_templates' );
add_action ( 'wp_footer' , 'wp_print_media_templates' );
}
Add new media workflow scripts, styles, and templates.
Please note that this commit does not integrate media into the existing UI. If you would like to see the new UI, navigate to the post editor and run the following in your browser's Javascript console:
new wp.media.controller.Workflow().render().modal.open();
The Javascript is broken up into two files, with the slugs media-models and media-views.
* media-models: The models are UI agnostic, and can be used independent of the views. If you'd like to create custom UIs, this is the script for you.
* media-views: This is the Media Experience. The views (and controllers) depend on the models (which are listed as a dependency and will automatically be included thanks to wp_enqueue_script). The views also require the media templates, media-view styles, and the plupload bridge settings. Perhaps we should create a function to include the whole shebang, but in the meantime...
To include media-views in the admin, run the following PHP in or after 'admin_enqueue_scripts':
wp_enqueue_script( 'media-views' );
wp_enqueue_style( 'media-views' );
wp_plupload_default_settings();
add_action( 'admin_footer', 'wp_print_media_templates' );
see #21390.
git-svn-id: http://core.svn.wordpress.org/trunk@21683 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2012-08-31 06:54:23 +02:00
/**
* Prints the templates used in the media manager .
*
* @ since 3.5 . 0
*/
function wp_print_media_templates ( $attachment ) {
?>
< script type = " text/html " id = " tmpl-media-modal " >
< div class = " media-modal " >
2012-11-14 22:51:41 +01:00
< h3 class = " media-modal-title " > {{ data . title }} </ h3 >
2012-10-10 11:40:22 +02:00
< a class = " media-modal-close " href = " " title = " <?php esc_attr_e('Close'); ?> " >& times ; </ a >
Add new media workflow scripts, styles, and templates.
Please note that this commit does not integrate media into the existing UI. If you would like to see the new UI, navigate to the post editor and run the following in your browser's Javascript console:
new wp.media.controller.Workflow().render().modal.open();
The Javascript is broken up into two files, with the slugs media-models and media-views.
* media-models: The models are UI agnostic, and can be used independent of the views. If you'd like to create custom UIs, this is the script for you.
* media-views: This is the Media Experience. The views (and controllers) depend on the models (which are listed as a dependency and will automatically be included thanks to wp_enqueue_script). The views also require the media templates, media-view styles, and the plupload bridge settings. Perhaps we should create a function to include the whole shebang, but in the meantime...
To include media-views in the admin, run the following PHP in or after 'admin_enqueue_scripts':
wp_enqueue_script( 'media-views' );
wp_enqueue_style( 'media-views' );
wp_plupload_default_settings();
add_action( 'admin_footer', 'wp_print_media_templates' );
see #21390.
git-svn-id: http://core.svn.wordpress.org/trunk@21683 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2012-08-31 06:54:23 +02:00
</ div >
Streamlining media, part I.
The main goal here is to rearrange the media components in a modularized structure to support more linear workflows. This is that structure using the pre-existing workflows, which will be improved over the course of the next few commits.
This leaves a few pieces a bit rough around the edges: namely gallery editing and selecting a featured image.
The fine print follows.
----
'''Styles'''
* Tightened padding around the modal to optimize for a smaller default screen size.
* Added a light dashed line surrounding the modal to provide a subtle cue for the persistent dropzone (which is evolving into a power user feature since we now have a dedicated `upload` state).
* Add a size for `hero` buttons.
* Remove transitions from frame subviews (e.g. menu, content, sidebar, toolbar).
----
'''Code'''
`wp.media.controller.StateManager`
* Don't fire `activate` and `deactivate` if attempting to switch to the current state.
`wp.media.controller.State`
* Add a base state class to bind default methods (as not all states will inherit from the `Library` state).
* On `activate`, fire `activate()`, `menu()`, `content()`, `sidebar()`, and `toolbar()`.
* The menu view is often a shared object (as its most common use case is switching between states). Assign the view to the state's `menu` attribute.
* `menu()` automatically fetches the state's `menu` attribute, attaches the menu view to the frame, and attempts to select a menu item that matches the state's `id`.
`wp.media.controller.Library`
* Now inherits from `wp.media.controller.State`.
`wp.media.controller.Upload`
* A new state to improve the upload experience.
* Displays a large dropzone when empty (a `UploaderInline` view).
* When attachments are uploaded, displays management interface (a `library` state restricted to attachments uploaded during the current session).
`wp.media.view.Frame`
* In `menu()`, `content()`, `sidebar()`, and `toolbar()`, only change the view if it differs from the current view. Also, ensure `hide-*` classes are properly removed.
*
`wp.media.view.PriorityList`
* A new container view used to sort and render child views by the `priority` property.
* Used by `wp.media.view.Sidebar` and `wp.media.view.Menu`.
* Next step: Use two instances to power `wp.media.view.Toolbar`.
`wp.media.view.Menu` and `wp.media.view.MenuItem`
* A new `PriorityList` view that renders a list of views used to switch between states.
* `MenuItem` instances have `id` attributes that are tied directly to states.
* Separators can be added as plain `Backbone.View` instances with the `separator` class.
* Supports any type of `Backbone.View`.
`media.view.Menu.Landing`
* The landing menu for the 'insert media' workflow.
* Includes an inactive link to an "Embed from URL" state.
* Next steps: only use in select cases to allot for other workflows (such as featured images).
`wp.media.view.AttachmentsBrowser`
* A container to render an `Attachments` view with accompanying UI controls (similar to what the `Attachments` view was when it contained the `$list` property).
* Currently only renders a `Search` view as a control.
* Next steps: Add optional view counts (e.g. "21 images"), upload buttons, and collection filter UI.
`wp.media.view.Attachments`
* If the `Attachments` scroll buffer is not filled with `Attachment` views, continue loading more attachments.
* Use `this.model` instead of `this.controller.state()` to allow `Attachments` views to have differing `edge` and `gutter` properties.
* Add `edge()`, a method used to calculate the optimal dimensions for an attachment based on the current width of the `Attachments` container element.
* `edge()` is currently only enabled on resize, as the relative positioning and CSS transforms used to center thumbnails are suboptimal when coupled with frequent resizing.
* Next steps: For infinite scroll performance improvements, look into absolutely positioning attachment views and paging groups of attachment views.
`wp.media.view.UploaderWindow`
* Now generates a `$browser` element as the browse button (instead of a full `UploaderInline` view). Using a portable browse button prevents us from having to create a new `wp.Uploader` instance every time we want access to a browse button.
`wp.media.view.UploaderInline`
* No longer directly linked to the `UploaderWindow` view or its `wp.Uploader` instance.
* Used as the default `upload` state view.
`wp.media.view.Selection`
* An interactive representation of the selected `Attachments`.
* Based on the improved workflows, this is likely overkill. For simplicity's sake, will probably remove this in favor of `SelectionPreview`.
----
see #21390.
git-svn-id: http://core.svn.wordpress.org/trunk@22362 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2012-11-04 23:59:12 +01:00
< div class = " media-modal-backdrop " >
< div ></ div >
</ div >
Add new media workflow scripts, styles, and templates.
Please note that this commit does not integrate media into the existing UI. If you would like to see the new UI, navigate to the post editor and run the following in your browser's Javascript console:
new wp.media.controller.Workflow().render().modal.open();
The Javascript is broken up into two files, with the slugs media-models and media-views.
* media-models: The models are UI agnostic, and can be used independent of the views. If you'd like to create custom UIs, this is the script for you.
* media-views: This is the Media Experience. The views (and controllers) depend on the models (which are listed as a dependency and will automatically be included thanks to wp_enqueue_script). The views also require the media templates, media-view styles, and the plupload bridge settings. Perhaps we should create a function to include the whole shebang, but in the meantime...
To include media-views in the admin, run the following PHP in or after 'admin_enqueue_scripts':
wp_enqueue_script( 'media-views' );
wp_enqueue_style( 'media-views' );
wp_plupload_default_settings();
add_action( 'admin_footer', 'wp_print_media_templates' );
see #21390.
git-svn-id: http://core.svn.wordpress.org/trunk@21683 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2012-08-31 06:54:23 +02:00
</ script >
2012-10-29 00:29:17 +01:00
< script type = " text/html " id = " tmpl-uploader-window " >
< div class = " uploader-window-content " >
2012-10-29 16:13:02 +01:00
< h3 >< ? php _e ( 'Drop files to upload' ); ?> </h3>
Add new media workflow scripts, styles, and templates.
Please note that this commit does not integrate media into the existing UI. If you would like to see the new UI, navigate to the post editor and run the following in your browser's Javascript console:
new wp.media.controller.Workflow().render().modal.open();
The Javascript is broken up into two files, with the slugs media-models and media-views.
* media-models: The models are UI agnostic, and can be used independent of the views. If you'd like to create custom UIs, this is the script for you.
* media-views: This is the Media Experience. The views (and controllers) depend on the models (which are listed as a dependency and will automatically be included thanks to wp_enqueue_script). The views also require the media templates, media-view styles, and the plupload bridge settings. Perhaps we should create a function to include the whole shebang, but in the meantime...
To include media-views in the admin, run the following PHP in or after 'admin_enqueue_scripts':
wp_enqueue_script( 'media-views' );
wp_enqueue_style( 'media-views' );
wp_plupload_default_settings();
add_action( 'admin_footer', 'wp_print_media_templates' );
see #21390.
git-svn-id: http://core.svn.wordpress.org/trunk@21683 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2012-08-31 06:54:23 +02:00
</ div >
</ script >
2012-10-29 08:38:13 +01:00
< script type = " text/html " id = " tmpl-uploader-inline " >
Streamlining media, part I.
The main goal here is to rearrange the media components in a modularized structure to support more linear workflows. This is that structure using the pre-existing workflows, which will be improved over the course of the next few commits.
This leaves a few pieces a bit rough around the edges: namely gallery editing and selecting a featured image.
The fine print follows.
----
'''Styles'''
* Tightened padding around the modal to optimize for a smaller default screen size.
* Added a light dashed line surrounding the modal to provide a subtle cue for the persistent dropzone (which is evolving into a power user feature since we now have a dedicated `upload` state).
* Add a size for `hero` buttons.
* Remove transitions from frame subviews (e.g. menu, content, sidebar, toolbar).
----
'''Code'''
`wp.media.controller.StateManager`
* Don't fire `activate` and `deactivate` if attempting to switch to the current state.
`wp.media.controller.State`
* Add a base state class to bind default methods (as not all states will inherit from the `Library` state).
* On `activate`, fire `activate()`, `menu()`, `content()`, `sidebar()`, and `toolbar()`.
* The menu view is often a shared object (as its most common use case is switching between states). Assign the view to the state's `menu` attribute.
* `menu()` automatically fetches the state's `menu` attribute, attaches the menu view to the frame, and attempts to select a menu item that matches the state's `id`.
`wp.media.controller.Library`
* Now inherits from `wp.media.controller.State`.
`wp.media.controller.Upload`
* A new state to improve the upload experience.
* Displays a large dropzone when empty (a `UploaderInline` view).
* When attachments are uploaded, displays management interface (a `library` state restricted to attachments uploaded during the current session).
`wp.media.view.Frame`
* In `menu()`, `content()`, `sidebar()`, and `toolbar()`, only change the view if it differs from the current view. Also, ensure `hide-*` classes are properly removed.
*
`wp.media.view.PriorityList`
* A new container view used to sort and render child views by the `priority` property.
* Used by `wp.media.view.Sidebar` and `wp.media.view.Menu`.
* Next step: Use two instances to power `wp.media.view.Toolbar`.
`wp.media.view.Menu` and `wp.media.view.MenuItem`
* A new `PriorityList` view that renders a list of views used to switch between states.
* `MenuItem` instances have `id` attributes that are tied directly to states.
* Separators can be added as plain `Backbone.View` instances with the `separator` class.
* Supports any type of `Backbone.View`.
`media.view.Menu.Landing`
* The landing menu for the 'insert media' workflow.
* Includes an inactive link to an "Embed from URL" state.
* Next steps: only use in select cases to allot for other workflows (such as featured images).
`wp.media.view.AttachmentsBrowser`
* A container to render an `Attachments` view with accompanying UI controls (similar to what the `Attachments` view was when it contained the `$list` property).
* Currently only renders a `Search` view as a control.
* Next steps: Add optional view counts (e.g. "21 images"), upload buttons, and collection filter UI.
`wp.media.view.Attachments`
* If the `Attachments` scroll buffer is not filled with `Attachment` views, continue loading more attachments.
* Use `this.model` instead of `this.controller.state()` to allow `Attachments` views to have differing `edge` and `gutter` properties.
* Add `edge()`, a method used to calculate the optimal dimensions for an attachment based on the current width of the `Attachments` container element.
* `edge()` is currently only enabled on resize, as the relative positioning and CSS transforms used to center thumbnails are suboptimal when coupled with frequent resizing.
* Next steps: For infinite scroll performance improvements, look into absolutely positioning attachment views and paging groups of attachment views.
`wp.media.view.UploaderWindow`
* Now generates a `$browser` element as the browse button (instead of a full `UploaderInline` view). Using a portable browse button prevents us from having to create a new `wp.Uploader` instance every time we want access to a browse button.
`wp.media.view.UploaderInline`
* No longer directly linked to the `UploaderWindow` view or its `wp.Uploader` instance.
* Used as the default `upload` state view.
`wp.media.view.Selection`
* An interactive representation of the selected `Attachments`.
* Based on the improved workflows, this is likely overkill. For simplicity's sake, will probably remove this in favor of `SelectionPreview`.
----
see #21390.
git-svn-id: http://core.svn.wordpress.org/trunk@22362 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2012-11-04 23:59:12 +01:00
< div class = " uploader-inline-content " >
2012-11-13 02:50:08 +01:00
< div class = " pre-upload-ui " >
< ? php do_action ( 'pre-upload-ui' ); ?>
< ? php do_action ( 'pre-plupload-upload-ui' ); ?>
</ div >
< div class = " upload-ui " >
< h3 >< ? php _e ( 'Drop files anywhere to upload' ); ?> </h3>
< a href = " # " class = " browser button button-hero " >< ? php _e ( 'Select Files' ); ?> </a>
</ div >
< div class = " post-upload-ui " >
< ? php do_action ( 'post-plupload-upload-ui' ); ?>
< ? php do_action ( 'post-upload-ui' ); ?>
</ div >
Streamlining media, part I.
The main goal here is to rearrange the media components in a modularized structure to support more linear workflows. This is that structure using the pre-existing workflows, which will be improved over the course of the next few commits.
This leaves a few pieces a bit rough around the edges: namely gallery editing and selecting a featured image.
The fine print follows.
----
'''Styles'''
* Tightened padding around the modal to optimize for a smaller default screen size.
* Added a light dashed line surrounding the modal to provide a subtle cue for the persistent dropzone (which is evolving into a power user feature since we now have a dedicated `upload` state).
* Add a size for `hero` buttons.
* Remove transitions from frame subviews (e.g. menu, content, sidebar, toolbar).
----
'''Code'''
`wp.media.controller.StateManager`
* Don't fire `activate` and `deactivate` if attempting to switch to the current state.
`wp.media.controller.State`
* Add a base state class to bind default methods (as not all states will inherit from the `Library` state).
* On `activate`, fire `activate()`, `menu()`, `content()`, `sidebar()`, and `toolbar()`.
* The menu view is often a shared object (as its most common use case is switching between states). Assign the view to the state's `menu` attribute.
* `menu()` automatically fetches the state's `menu` attribute, attaches the menu view to the frame, and attempts to select a menu item that matches the state's `id`.
`wp.media.controller.Library`
* Now inherits from `wp.media.controller.State`.
`wp.media.controller.Upload`
* A new state to improve the upload experience.
* Displays a large dropzone when empty (a `UploaderInline` view).
* When attachments are uploaded, displays management interface (a `library` state restricted to attachments uploaded during the current session).
`wp.media.view.Frame`
* In `menu()`, `content()`, `sidebar()`, and `toolbar()`, only change the view if it differs from the current view. Also, ensure `hide-*` classes are properly removed.
*
`wp.media.view.PriorityList`
* A new container view used to sort and render child views by the `priority` property.
* Used by `wp.media.view.Sidebar` and `wp.media.view.Menu`.
* Next step: Use two instances to power `wp.media.view.Toolbar`.
`wp.media.view.Menu` and `wp.media.view.MenuItem`
* A new `PriorityList` view that renders a list of views used to switch between states.
* `MenuItem` instances have `id` attributes that are tied directly to states.
* Separators can be added as plain `Backbone.View` instances with the `separator` class.
* Supports any type of `Backbone.View`.
`media.view.Menu.Landing`
* The landing menu for the 'insert media' workflow.
* Includes an inactive link to an "Embed from URL" state.
* Next steps: only use in select cases to allot for other workflows (such as featured images).
`wp.media.view.AttachmentsBrowser`
* A container to render an `Attachments` view with accompanying UI controls (similar to what the `Attachments` view was when it contained the `$list` property).
* Currently only renders a `Search` view as a control.
* Next steps: Add optional view counts (e.g. "21 images"), upload buttons, and collection filter UI.
`wp.media.view.Attachments`
* If the `Attachments` scroll buffer is not filled with `Attachment` views, continue loading more attachments.
* Use `this.model` instead of `this.controller.state()` to allow `Attachments` views to have differing `edge` and `gutter` properties.
* Add `edge()`, a method used to calculate the optimal dimensions for an attachment based on the current width of the `Attachments` container element.
* `edge()` is currently only enabled on resize, as the relative positioning and CSS transforms used to center thumbnails are suboptimal when coupled with frequent resizing.
* Next steps: For infinite scroll performance improvements, look into absolutely positioning attachment views and paging groups of attachment views.
`wp.media.view.UploaderWindow`
* Now generates a `$browser` element as the browse button (instead of a full `UploaderInline` view). Using a portable browse button prevents us from having to create a new `wp.Uploader` instance every time we want access to a browse button.
`wp.media.view.UploaderInline`
* No longer directly linked to the `UploaderWindow` view or its `wp.Uploader` instance.
* Used as the default `upload` state view.
`wp.media.view.Selection`
* An interactive representation of the selected `Attachments`.
* Based on the improved workflows, this is likely overkill. For simplicity's sake, will probably remove this in favor of `SelectionPreview`.
----
see #21390.
git-svn-id: http://core.svn.wordpress.org/trunk@22362 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2012-11-04 23:59:12 +01:00
</ div >
Add new media workflow scripts, styles, and templates.
Please note that this commit does not integrate media into the existing UI. If you would like to see the new UI, navigate to the post editor and run the following in your browser's Javascript console:
new wp.media.controller.Workflow().render().modal.open();
The Javascript is broken up into two files, with the slugs media-models and media-views.
* media-models: The models are UI agnostic, and can be used independent of the views. If you'd like to create custom UIs, this is the script for you.
* media-views: This is the Media Experience. The views (and controllers) depend on the models (which are listed as a dependency and will automatically be included thanks to wp_enqueue_script). The views also require the media templates, media-view styles, and the plupload bridge settings. Perhaps we should create a function to include the whole shebang, but in the meantime...
To include media-views in the admin, run the following PHP in or after 'admin_enqueue_scripts':
wp_enqueue_script( 'media-views' );
wp_enqueue_style( 'media-views' );
wp_plupload_default_settings();
add_action( 'admin_footer', 'wp_print_media_templates' );
see #21390.
git-svn-id: http://core.svn.wordpress.org/trunk@21683 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2012-08-31 06:54:23 +02:00
</ script >
< script type = " text/html " id = " tmpl-attachment " >
2012-11-14 22:51:41 +01:00
< div class = " attachment-preview type- { { data.type }} subtype- { { data.subtype }} { { data.orientation }} " >
< # if ( data.uploading ) { #>
2012-10-11 02:36:42 +02:00
< div class = " media-progress-bar " >< div ></ div ></ div >
2012-11-14 22:51:41 +01:00
< # } else if ( 'image' === data.type ) { #>
2012-10-09 01:20:04 +02:00
< div class = " thumbnail " >
2012-10-31 21:34:50 +01:00
< div class = " centered " >
2012-11-14 23:08:02 +01:00
< img src = " { { data.size.url }} " draggable = " false " />
2012-10-31 21:34:50 +01:00
</ div >
2012-10-09 01:20:04 +02:00
</ div >
2012-11-07 09:41:17 +01:00
< # } else { #>
2012-11-14 22:51:41 +01:00
< img src = " { { data.icon }} " class = " icon " draggable = " false " />
< div class = " filename " > {{ data . filename }} </ div >
2012-11-07 09:41:17 +01:00
< # } #>
Add new media workflow scripts, styles, and templates.
Please note that this commit does not integrate media into the existing UI. If you would like to see the new UI, navigate to the post editor and run the following in your browser's Javascript console:
new wp.media.controller.Workflow().render().modal.open();
The Javascript is broken up into two files, with the slugs media-models and media-views.
* media-models: The models are UI agnostic, and can be used independent of the views. If you'd like to create custom UIs, this is the script for you.
* media-views: This is the Media Experience. The views (and controllers) depend on the models (which are listed as a dependency and will automatically be included thanks to wp_enqueue_script). The views also require the media templates, media-view styles, and the plupload bridge settings. Perhaps we should create a function to include the whole shebang, but in the meantime...
To include media-views in the admin, run the following PHP in or after 'admin_enqueue_scripts':
wp_enqueue_script( 'media-views' );
wp_enqueue_style( 'media-views' );
wp_plupload_default_settings();
add_action( 'admin_footer', 'wp_print_media_templates' );
see #21390.
git-svn-id: http://core.svn.wordpress.org/trunk@21683 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2012-08-31 06:54:23 +02:00
2012-11-14 22:51:41 +01:00
< # if ( data.buttons.close ) { #>
2012-10-11 06:11:47 +02:00
< a class = " close button " href = " # " >& times ; </ a >
2012-11-07 09:41:17 +01:00
< # } #>
Add new media workflow scripts, styles, and templates.
Please note that this commit does not integrate media into the existing UI. If you would like to see the new UI, navigate to the post editor and run the following in your browser's Javascript console:
new wp.media.controller.Workflow().render().modal.open();
The Javascript is broken up into two files, with the slugs media-models and media-views.
* media-models: The models are UI agnostic, and can be used independent of the views. If you'd like to create custom UIs, this is the script for you.
* media-views: This is the Media Experience. The views (and controllers) depend on the models (which are listed as a dependency and will automatically be included thanks to wp_enqueue_script). The views also require the media templates, media-view styles, and the plupload bridge settings. Perhaps we should create a function to include the whole shebang, but in the meantime...
To include media-views in the admin, run the following PHP in or after 'admin_enqueue_scripts':
wp_enqueue_script( 'media-views' );
wp_enqueue_style( 'media-views' );
wp_plupload_default_settings();
add_action( 'admin_footer', 'wp_print_media_templates' );
see #21390.
git-svn-id: http://core.svn.wordpress.org/trunk@21683 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2012-08-31 06:54:23 +02:00
</ div >
2012-11-14 22:51:41 +01:00
< # if ( data.describe ) { #>
< # if ( 'image' === data.type ) { #>
2012-10-11 01:32:48 +02:00
< textarea class = " describe "
placeholder = " <?php esc_attr_e('Describe this image…'); ?> "
2012-11-14 22:51:41 +01:00
> {{ data . caption }} </ textarea >
2012-11-07 09:41:17 +01:00
< # } else { #>
2012-10-11 01:32:48 +02:00
< textarea class = " describe "
2012-11-14 22:51:41 +01:00
< # if ( 'video' === data.type ) { #>
2012-10-11 01:32:48 +02:00
placeholder = " <?php esc_attr_e('Describe this video…'); ?> "
2012-11-14 22:51:41 +01:00
< # } else if ( 'audio' === data.type ) { #>
2012-10-11 01:32:48 +02:00
placeholder = " <?php esc_attr_e('Describe this audio file…'); ?> "
2012-11-07 09:41:17 +01:00
< # } else { #>
2012-10-11 01:32:48 +02:00
placeholder = " <?php esc_attr_e('Describe this media file…'); ?> "
2012-11-07 09:41:17 +01:00
< # } #>
2012-11-14 22:51:41 +01:00
> {{ data . title }} </ textarea >
2012-11-07 09:41:17 +01:00
< # } #>
< # } #>
Add new media workflow scripts, styles, and templates.
Please note that this commit does not integrate media into the existing UI. If you would like to see the new UI, navigate to the post editor and run the following in your browser's Javascript console:
new wp.media.controller.Workflow().render().modal.open();
The Javascript is broken up into two files, with the slugs media-models and media-views.
* media-models: The models are UI agnostic, and can be used independent of the views. If you'd like to create custom UIs, this is the script for you.
* media-views: This is the Media Experience. The views (and controllers) depend on the models (which are listed as a dependency and will automatically be included thanks to wp_enqueue_script). The views also require the media templates, media-view styles, and the plupload bridge settings. Perhaps we should create a function to include the whole shebang, but in the meantime...
To include media-views in the admin, run the following PHP in or after 'admin_enqueue_scripts':
wp_enqueue_script( 'media-views' );
wp_enqueue_style( 'media-views' );
wp_plupload_default_settings();
add_action( 'admin_footer', 'wp_print_media_templates' );
see #21390.
git-svn-id: http://core.svn.wordpress.org/trunk@21683 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2012-08-31 06:54:23 +02:00
</ script >
2012-09-06 09:46:15 +02:00
2012-10-29 16:13:02 +01:00
< script type = " text/html " id = " tmpl-attachment-details " >
2012-11-10 19:25:04 +01:00
< h3 >< ? php _e ( 'Attachment Details' ); ?> </h3>
< div class = " attachment-info " >
< div class = " thumbnail " >
2012-11-14 22:51:41 +01:00
< # if ( data.uploading ) { #>
2012-11-10 19:25:04 +01:00
< div class = " media-progress-bar " >< div ></ div ></ div >
2012-11-14 22:51:41 +01:00
< # } else if ( 'image' === data.type ) { #>
2012-11-14 23:08:02 +01:00
< img src = " { { data.size.url }} " draggable = " false " />
2012-11-10 19:25:04 +01:00
< # } else { #>
2012-11-14 22:51:41 +01:00
< img src = " { { data.icon }} " class = " icon " draggable = " false " />
2012-11-10 19:25:04 +01:00
< # } #>
</ div >
< div class = " details " >
2012-11-14 22:51:41 +01:00
< div class = " filename " > {{ data . filename }} </ div >
< div class = " uploaded " > {{ data . dateFormatted }} </ div >
< # if ( 'image' === data.type && ! data.uploading ) { #>
< div class = " dimensions " > {{ data . width }} & times ; {{ data . height }} </ div >
2012-11-10 19:25:04 +01:00
< # } #>
</ div >
2012-11-11 02:26:42 +01:00
< div class = " compat-meta " >
2012-11-14 22:51:41 +01:00
< # if ( data.compat && data.compat.meta ) { #>
{{{ data . compat . meta }}}
2012-11-11 02:26:42 +01:00
< # } #>
</ div >
2012-10-29 16:13:02 +01:00
</ div >
2012-11-14 22:51:41 +01:00
< # if ( 'image' === data.type ) { #>
2012-11-10 19:25:04 +01:00
< label class = " setting " data - setting = " title " >
< span >< ? php _e ( 'Title' ); ?> </span>
2012-11-14 22:51:41 +01:00
< input type = " text " value = " { { data.title }} " />
2012-11-10 19:25:04 +01:00
</ label >
< label class = " setting " data - setting = " caption " >
< span >< ? php _e ( 'Caption' ); ?> </span>
< textarea
placeholder = " <?php esc_attr_e('Describe this image…'); ?> "
2012-11-14 22:51:41 +01:00
> {{ data . caption }} </ textarea >
2012-11-10 19:25:04 +01:00
</ label >
< label class = " setting " data - setting = " alt " >
< span >< ? php _e ( 'Alt Text' ); ?> </span>
2012-11-14 22:51:41 +01:00
< input type = " text " value = " { { data.alt }} " />
2012-11-10 19:25:04 +01:00
</ label >
2012-11-07 09:41:17 +01:00
< # } else { #>
2012-11-10 19:25:04 +01:00
< label class = " setting " data - setting = " title " >
< span >< ? php _e ( 'Title' ); ?> </span>
2012-11-14 22:51:41 +01:00
< input type = " text " value = " { { data.title }} "
< # if ( 'video' === data.type ) { #>
2012-10-29 16:13:02 +01:00
placeholder = " <?php esc_attr_e('Describe this video…'); ?> "
2012-11-14 22:51:41 +01:00
< # } else if ( 'audio' === data.type ) { #>
2012-10-29 16:13:02 +01:00
placeholder = " <?php esc_attr_e('Describe this audio file…'); ?> "
2012-11-07 09:41:17 +01:00
< # } else { #>
2012-10-29 16:13:02 +01:00
placeholder = " <?php esc_attr_e('Describe this media file…'); ?> "
2012-11-10 19:25:04 +01:00
< # } #>/>
</ label >
2012-11-07 09:41:17 +01:00
< # } #>
2012-10-29 16:13:02 +01:00
</ script >
Streamlining media, part I.
The main goal here is to rearrange the media components in a modularized structure to support more linear workflows. This is that structure using the pre-existing workflows, which will be improved over the course of the next few commits.
This leaves a few pieces a bit rough around the edges: namely gallery editing and selecting a featured image.
The fine print follows.
----
'''Styles'''
* Tightened padding around the modal to optimize for a smaller default screen size.
* Added a light dashed line surrounding the modal to provide a subtle cue for the persistent dropzone (which is evolving into a power user feature since we now have a dedicated `upload` state).
* Add a size for `hero` buttons.
* Remove transitions from frame subviews (e.g. menu, content, sidebar, toolbar).
----
'''Code'''
`wp.media.controller.StateManager`
* Don't fire `activate` and `deactivate` if attempting to switch to the current state.
`wp.media.controller.State`
* Add a base state class to bind default methods (as not all states will inherit from the `Library` state).
* On `activate`, fire `activate()`, `menu()`, `content()`, `sidebar()`, and `toolbar()`.
* The menu view is often a shared object (as its most common use case is switching between states). Assign the view to the state's `menu` attribute.
* `menu()` automatically fetches the state's `menu` attribute, attaches the menu view to the frame, and attempts to select a menu item that matches the state's `id`.
`wp.media.controller.Library`
* Now inherits from `wp.media.controller.State`.
`wp.media.controller.Upload`
* A new state to improve the upload experience.
* Displays a large dropzone when empty (a `UploaderInline` view).
* When attachments are uploaded, displays management interface (a `library` state restricted to attachments uploaded during the current session).
`wp.media.view.Frame`
* In `menu()`, `content()`, `sidebar()`, and `toolbar()`, only change the view if it differs from the current view. Also, ensure `hide-*` classes are properly removed.
*
`wp.media.view.PriorityList`
* A new container view used to sort and render child views by the `priority` property.
* Used by `wp.media.view.Sidebar` and `wp.media.view.Menu`.
* Next step: Use two instances to power `wp.media.view.Toolbar`.
`wp.media.view.Menu` and `wp.media.view.MenuItem`
* A new `PriorityList` view that renders a list of views used to switch between states.
* `MenuItem` instances have `id` attributes that are tied directly to states.
* Separators can be added as plain `Backbone.View` instances with the `separator` class.
* Supports any type of `Backbone.View`.
`media.view.Menu.Landing`
* The landing menu for the 'insert media' workflow.
* Includes an inactive link to an "Embed from URL" state.
* Next steps: only use in select cases to allot for other workflows (such as featured images).
`wp.media.view.AttachmentsBrowser`
* A container to render an `Attachments` view with accompanying UI controls (similar to what the `Attachments` view was when it contained the `$list` property).
* Currently only renders a `Search` view as a control.
* Next steps: Add optional view counts (e.g. "21 images"), upload buttons, and collection filter UI.
`wp.media.view.Attachments`
* If the `Attachments` scroll buffer is not filled with `Attachment` views, continue loading more attachments.
* Use `this.model` instead of `this.controller.state()` to allow `Attachments` views to have differing `edge` and `gutter` properties.
* Add `edge()`, a method used to calculate the optimal dimensions for an attachment based on the current width of the `Attachments` container element.
* `edge()` is currently only enabled on resize, as the relative positioning and CSS transforms used to center thumbnails are suboptimal when coupled with frequent resizing.
* Next steps: For infinite scroll performance improvements, look into absolutely positioning attachment views and paging groups of attachment views.
`wp.media.view.UploaderWindow`
* Now generates a `$browser` element as the browse button (instead of a full `UploaderInline` view). Using a portable browse button prevents us from having to create a new `wp.Uploader` instance every time we want access to a browse button.
`wp.media.view.UploaderInline`
* No longer directly linked to the `UploaderWindow` view or its `wp.Uploader` instance.
* Used as the default `upload` state view.
`wp.media.view.Selection`
* An interactive representation of the selected `Attachments`.
* Based on the improved workflows, this is likely overkill. For simplicity's sake, will probably remove this in favor of `SelectionPreview`.
----
see #21390.
git-svn-id: http://core.svn.wordpress.org/trunk@22362 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2012-11-04 23:59:12 +01:00
< script type = " text/html " id = " tmpl-media-selection " >
< div class = " selection-info " >
< span class = " count " ></ span >
2012-11-14 22:51:41 +01:00
< # if ( data.clearable ) { #>
Streamlining media, part I.
The main goal here is to rearrange the media components in a modularized structure to support more linear workflows. This is that structure using the pre-existing workflows, which will be improved over the course of the next few commits.
This leaves a few pieces a bit rough around the edges: namely gallery editing and selecting a featured image.
The fine print follows.
----
'''Styles'''
* Tightened padding around the modal to optimize for a smaller default screen size.
* Added a light dashed line surrounding the modal to provide a subtle cue for the persistent dropzone (which is evolving into a power user feature since we now have a dedicated `upload` state).
* Add a size for `hero` buttons.
* Remove transitions from frame subviews (e.g. menu, content, sidebar, toolbar).
----
'''Code'''
`wp.media.controller.StateManager`
* Don't fire `activate` and `deactivate` if attempting to switch to the current state.
`wp.media.controller.State`
* Add a base state class to bind default methods (as not all states will inherit from the `Library` state).
* On `activate`, fire `activate()`, `menu()`, `content()`, `sidebar()`, and `toolbar()`.
* The menu view is often a shared object (as its most common use case is switching between states). Assign the view to the state's `menu` attribute.
* `menu()` automatically fetches the state's `menu` attribute, attaches the menu view to the frame, and attempts to select a menu item that matches the state's `id`.
`wp.media.controller.Library`
* Now inherits from `wp.media.controller.State`.
`wp.media.controller.Upload`
* A new state to improve the upload experience.
* Displays a large dropzone when empty (a `UploaderInline` view).
* When attachments are uploaded, displays management interface (a `library` state restricted to attachments uploaded during the current session).
`wp.media.view.Frame`
* In `menu()`, `content()`, `sidebar()`, and `toolbar()`, only change the view if it differs from the current view. Also, ensure `hide-*` classes are properly removed.
*
`wp.media.view.PriorityList`
* A new container view used to sort and render child views by the `priority` property.
* Used by `wp.media.view.Sidebar` and `wp.media.view.Menu`.
* Next step: Use two instances to power `wp.media.view.Toolbar`.
`wp.media.view.Menu` and `wp.media.view.MenuItem`
* A new `PriorityList` view that renders a list of views used to switch between states.
* `MenuItem` instances have `id` attributes that are tied directly to states.
* Separators can be added as plain `Backbone.View` instances with the `separator` class.
* Supports any type of `Backbone.View`.
`media.view.Menu.Landing`
* The landing menu for the 'insert media' workflow.
* Includes an inactive link to an "Embed from URL" state.
* Next steps: only use in select cases to allot for other workflows (such as featured images).
`wp.media.view.AttachmentsBrowser`
* A container to render an `Attachments` view with accompanying UI controls (similar to what the `Attachments` view was when it contained the `$list` property).
* Currently only renders a `Search` view as a control.
* Next steps: Add optional view counts (e.g. "21 images"), upload buttons, and collection filter UI.
`wp.media.view.Attachments`
* If the `Attachments` scroll buffer is not filled with `Attachment` views, continue loading more attachments.
* Use `this.model` instead of `this.controller.state()` to allow `Attachments` views to have differing `edge` and `gutter` properties.
* Add `edge()`, a method used to calculate the optimal dimensions for an attachment based on the current width of the `Attachments` container element.
* `edge()` is currently only enabled on resize, as the relative positioning and CSS transforms used to center thumbnails are suboptimal when coupled with frequent resizing.
* Next steps: For infinite scroll performance improvements, look into absolutely positioning attachment views and paging groups of attachment views.
`wp.media.view.UploaderWindow`
* Now generates a `$browser` element as the browse button (instead of a full `UploaderInline` view). Using a portable browse button prevents us from having to create a new `wp.Uploader` instance every time we want access to a browse button.
`wp.media.view.UploaderInline`
* No longer directly linked to the `UploaderWindow` view or its `wp.Uploader` instance.
* Used as the default `upload` state view.
`wp.media.view.Selection`
* An interactive representation of the selected `Attachments`.
* Based on the improved workflows, this is likely overkill. For simplicity's sake, will probably remove this in favor of `SelectionPreview`.
----
see #21390.
git-svn-id: http://core.svn.wordpress.org/trunk@22362 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2012-11-04 23:59:12 +01:00
< a class = " clear-selection " href = " # " >< ? php _e ( 'Clear' ); ?> </a>
2012-11-07 09:41:17 +01:00
< # } #>
Streamlining media, part I.
The main goal here is to rearrange the media components in a modularized structure to support more linear workflows. This is that structure using the pre-existing workflows, which will be improved over the course of the next few commits.
This leaves a few pieces a bit rough around the edges: namely gallery editing and selecting a featured image.
The fine print follows.
----
'''Styles'''
* Tightened padding around the modal to optimize for a smaller default screen size.
* Added a light dashed line surrounding the modal to provide a subtle cue for the persistent dropzone (which is evolving into a power user feature since we now have a dedicated `upload` state).
* Add a size for `hero` buttons.
* Remove transitions from frame subviews (e.g. menu, content, sidebar, toolbar).
----
'''Code'''
`wp.media.controller.StateManager`
* Don't fire `activate` and `deactivate` if attempting to switch to the current state.
`wp.media.controller.State`
* Add a base state class to bind default methods (as not all states will inherit from the `Library` state).
* On `activate`, fire `activate()`, `menu()`, `content()`, `sidebar()`, and `toolbar()`.
* The menu view is often a shared object (as its most common use case is switching between states). Assign the view to the state's `menu` attribute.
* `menu()` automatically fetches the state's `menu` attribute, attaches the menu view to the frame, and attempts to select a menu item that matches the state's `id`.
`wp.media.controller.Library`
* Now inherits from `wp.media.controller.State`.
`wp.media.controller.Upload`
* A new state to improve the upload experience.
* Displays a large dropzone when empty (a `UploaderInline` view).
* When attachments are uploaded, displays management interface (a `library` state restricted to attachments uploaded during the current session).
`wp.media.view.Frame`
* In `menu()`, `content()`, `sidebar()`, and `toolbar()`, only change the view if it differs from the current view. Also, ensure `hide-*` classes are properly removed.
*
`wp.media.view.PriorityList`
* A new container view used to sort and render child views by the `priority` property.
* Used by `wp.media.view.Sidebar` and `wp.media.view.Menu`.
* Next step: Use two instances to power `wp.media.view.Toolbar`.
`wp.media.view.Menu` and `wp.media.view.MenuItem`
* A new `PriorityList` view that renders a list of views used to switch between states.
* `MenuItem` instances have `id` attributes that are tied directly to states.
* Separators can be added as plain `Backbone.View` instances with the `separator` class.
* Supports any type of `Backbone.View`.
`media.view.Menu.Landing`
* The landing menu for the 'insert media' workflow.
* Includes an inactive link to an "Embed from URL" state.
* Next steps: only use in select cases to allot for other workflows (such as featured images).
`wp.media.view.AttachmentsBrowser`
* A container to render an `Attachments` view with accompanying UI controls (similar to what the `Attachments` view was when it contained the `$list` property).
* Currently only renders a `Search` view as a control.
* Next steps: Add optional view counts (e.g. "21 images"), upload buttons, and collection filter UI.
`wp.media.view.Attachments`
* If the `Attachments` scroll buffer is not filled with `Attachment` views, continue loading more attachments.
* Use `this.model` instead of `this.controller.state()` to allow `Attachments` views to have differing `edge` and `gutter` properties.
* Add `edge()`, a method used to calculate the optimal dimensions for an attachment based on the current width of the `Attachments` container element.
* `edge()` is currently only enabled on resize, as the relative positioning and CSS transforms used to center thumbnails are suboptimal when coupled with frequent resizing.
* Next steps: For infinite scroll performance improvements, look into absolutely positioning attachment views and paging groups of attachment views.
`wp.media.view.UploaderWindow`
* Now generates a `$browser` element as the browse button (instead of a full `UploaderInline` view). Using a portable browse button prevents us from having to create a new `wp.Uploader` instance every time we want access to a browse button.
`wp.media.view.UploaderInline`
* No longer directly linked to the `UploaderWindow` view or its `wp.Uploader` instance.
* Used as the default `upload` state view.
`wp.media.view.Selection`
* An interactive representation of the selected `Attachments`.
* Based on the improved workflows, this is likely overkill. For simplicity's sake, will probably remove this in favor of `SelectionPreview`.
----
see #21390.
git-svn-id: http://core.svn.wordpress.org/trunk@22362 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2012-11-04 23:59:12 +01:00
</ div >
< div class = " selection-view " ></ div >
</ script >
2012-09-06 09:46:15 +02:00
< script type = " text/html " id = " tmpl-media-selection-preview " >
2012-11-14 22:51:41 +01:00
< div class = " selected-img selected-count- { { data.count }} " >
< # if ( data.thumbnail ) { #>
< img src = " { { data.thumbnail }} " draggable = " false " />
2012-11-07 09:41:17 +01:00
< # } #>
2012-09-06 09:46:15 +02:00
2012-11-14 22:51:41 +01:00
< span class = " count " > {{ data . count }} </ span >
2012-09-06 09:46:15 +02:00
</ div >
2012-11-14 22:51:41 +01:00
< # if ( data.clearable ) { #>
2012-10-10 11:30:22 +02:00
< a class = " clear-selection " href = " # " >< ? php _e ( 'Clear selection' ); ?> </a>
2012-11-07 09:41:17 +01:00
< # } #>
2012-09-06 09:46:15 +02:00
</ script >
2012-09-26 16:12:54 +02:00
2012-10-16 21:25:17 +02:00
< script type = " text/html " id = " tmpl-attachment-display-settings " >
2012-11-07 21:14:41 +01:00
< h3 >< ? php _e ( 'Attachment Display Settings' ); ?> </h3>
2012-11-10 19:25:04 +01:00
< label class = " setting " >
< span >< ? php _e ( 'Alignment' ); ?> </span>
< select class = " alignment "
data - setting = " align "
2012-11-14 22:51:41 +01:00
< # if ( data.userSettings ) { #>
2012-11-10 19:25:04 +01:00
data - user - setting = " align "
< # } #>>
2012-10-16 21:25:17 +02:00
2012-11-10 19:25:04 +01:00
< option value = " left " >
< ? php esc_attr_e ( 'Left' ); ?>
</ option >
< option value = " center " >
< ? php esc_attr_e ( 'Center' ); ?>
</ option >
< option value = " right " >
< ? php esc_attr_e ( 'Right' ); ?>
</ option >
< option value = " none " selected >
< ? php esc_attr_e ( 'None' ); ?>
</ option >
</ select >
</ label >
2012-11-09 07:15:25 +01:00
2012-11-10 21:36:46 +01:00
< div class = " setting " >
< label >
< span >< ? php _e ( 'Link To' ); ?> </span>
< select class = " link-to "
data - setting = " link "
2012-11-14 22:51:41 +01:00
< # if ( data.userSettings ) { #>
2012-11-10 21:36:46 +01:00
data - user - setting = " urlbutton "
< # } #>>
2012-11-09 07:15:25 +01:00
2012-11-10 21:36:46 +01:00
< option value = " custom " >
< ? php esc_attr_e ( 'Custom URL' ); ?>
</ option >
< option value = " post " selected >
< ? php esc_attr_e ( 'Attachment Page' ); ?>
</ option >
< option value = " file " >
< ? php esc_attr_e ( 'Media File' ); ?>
</ option >
< option value = " none " >
< ? php esc_attr_e ( 'None' ); ?>
</ option >
</ select >
</ label >
< input type = " text " class = " link-to-custom " data - setting = " linkUrl " />
</ div >
2012-11-10 19:25:04 +01:00
2012-11-14 22:51:41 +01:00
< # if ( 'undefined' !== typeof data.sizes ) { #>
2012-11-10 19:25:04 +01:00
< label class = " setting " >
< span >< ? php _e ( 'Size' ); ?> </span>
< select class = " size " name = " size "
data - setting = " size "
2012-11-14 22:51:41 +01:00
< # if ( data.userSettings ) { #>
2012-11-10 19:25:04 +01:00
data - user - setting = " imgsize "
< # } #>>
< ? php
$sizes = apply_filters ( 'image_size_names_choose' , array (
'thumbnail' => __ ( 'Thumbnail' ),
'medium' => __ ( 'Medium' ),
'large' => __ ( 'Large' ),
2012-11-13 02:23:18 +01:00
'full' => __ ( 'Full Size' ),
2012-11-10 19:25:04 +01:00
) );
2012-11-14 23:08:02 +01:00
foreach ( $sizes as $value => $name ) : ?>
< #
var size = data . sizes [ '<?php echo esc_js( $value ); ?>' ];
if ( size ) { #>
2012-11-10 19:25:04 +01:00
< option value = " <?php echo esc_attr( $value ); ?> " < ? php selected ( $value , 'medium' ); ?> >
2012-11-14 23:08:02 +01:00
< ? php echo esc_html ( $name ); ?> – {{ size.width }} × {{ size.height }}
2012-11-10 19:25:04 +01:00
</ option >
< # } #>>
2012-11-14 23:08:02 +01:00
< ? php endforeach ; ?>
2012-11-10 19:25:04 +01:00
</ select >
</ label >
2012-11-09 07:15:25 +01:00
< # } #>
2012-10-16 21:25:17 +02:00
</ script >
2012-10-31 20:22:25 +01:00
< script type = " text/html " id = " tmpl-gallery-settings " >
2012-11-07 21:14:41 +01:00
< h3 >< ? php _e ( 'Gallery Settings' ); ?> </h3>
2012-11-10 19:25:04 +01:00
< label class = " setting " >
< span >< ? php _e ( 'Link To' ); ?> </span>
< select class = " link-to "
data - setting = " link "
2012-11-14 22:51:41 +01:00
< # if ( data.userSettings ) { #>
2012-11-10 19:25:04 +01:00
data - user - setting = " urlbutton "
< # } #>>
2012-10-31 20:22:25 +01:00
2012-11-10 19:25:04 +01:00
< option value = " post " selected >
< ? php esc_attr_e ( 'Attachment Page' ); ?>
</ option >
< option value = " file " >
< ? php esc_attr_e ( 'Media File' ); ?>
2012-11-07 09:41:17 +01:00
</ option >
2012-11-10 19:25:04 +01:00
</ select >
</ label >
< label class = " setting " >
< span >< ? php _e ( 'Columns' ); ?> </span>
< select class = " columns " name = " columns "
data - setting = " columns " >
< ? php for ( $i = 1 ; $i <= 9 ; $i ++ ) : ?>
< option value = " <?php echo esc_attr( $i ); ?> " < ? php selected ( $i , 3 ); ?> >
< ? php echo esc_html ( $i ); ?>
</ option >
< ? php endfor ; ?>
</ select >
</ label >
2012-10-31 20:22:25 +01:00
</ script >
2012-11-12 06:57:12 +01:00
< script type = " text/html " id = " tmpl-embed-link-settings " >
< label class = " setting " >
< span >< ? php _e ( 'Title' ); ?> </span>
< input type = " text " class = " alignment " data - setting = " title " />
</ label >
</ script >
< script type = " text/html " id = " tmpl-embed-image-settings " >
< div class = " thumbnail " >
2012-11-14 22:51:41 +01:00
< img src = " { { data.model.url }} " draggable = " false " />
2012-11-12 06:57:12 +01:00
</ div >
< label class = " setting caption " >
< span >< ? php _e ( 'Caption' ); ?> </span>
< textarea data - setting = " caption " />
</ label >
< label class = " setting alt-text " >
< span >< ? php _e ( 'Alt Text' ); ?> </span>
< input type = " text " data - setting = " alt " />
</ label >
< label class = " setting align " >
< span >< ? php _e ( 'Align' ); ?> </span>
< div class = " button-group button-large " data - setting = " align " >
< button class = " button " value = " left " >
< ? php esc_attr_e ( 'Left' ); ?>
</ button >
< button class = " button " value = " center " >
< ? php esc_attr_e ( 'Center' ); ?>
</ button >
< button class = " button " value = " right " >
< ? php esc_attr_e ( 'Right' ); ?>
</ button >
< button class = " button active " value = " none " >
< ? php esc_attr_e ( 'None' ); ?>
</ button >
</ div >
</ label >
< div class = " setting link-to " >
< span >< ? php _e ( 'Link To' ); ?> </span>
< div class = " button-group button-large " data - setting = " link " >
< button class = " button " value = " file " >
< ? php esc_attr_e ( 'Image URL' ); ?>
</ button >
< button class = " button " value = " custom " >
< ? php esc_attr_e ( 'Custom URL' ); ?>
</ button >
< button class = " button active " value = " none " >
< ? php esc_attr_e ( 'None' ); ?>
</ button >
</ div >
< input type = " text " class = " link-to-custom " data - setting = " linkUrl " />
</ div >
</ script >
2012-10-29 19:05:03 +01:00
< script type = " text/html " id = " tmpl-attachments-css " >
2012-11-14 22:51:41 +01:00
< style type = " text/css " id = " { { data.id }}-css " >
#{{ data.id }} {
padding : 0 {{ data . gutter }} px ;
2012-10-29 19:05:03 +01:00
}
2012-11-14 22:51:41 +01:00
#{{ data.id }} .attachment {
margin : {{ data . gutter }} px ;
width : {{ data . edge }} px ;
2012-10-29 19:05:03 +01:00
}
2012-11-14 22:51:41 +01:00
#{{ data.id }} .attachment-preview,
#{{ data.id }} .attachment-preview .thumbnail {
width : {{ data . edge }} px ;
height : {{ data . edge }} px ;
2012-10-29 19:05:03 +01:00
}
2012-11-14 22:51:41 +01:00
#{{ data.id }} .portrait .thumbnail img {
width : {{ data . edge }} px ;
2012-10-29 19:05:03 +01:00
height : auto ;
}
2012-11-14 22:51:41 +01:00
#{{ data.id }} .landscape .thumbnail img {
2012-10-29 19:05:03 +01:00
width : auto ;
2012-11-14 22:51:41 +01:00
height : {{ data . edge }} px ;
2012-10-29 19:05:03 +01:00
}
</ style >
</ script >
Add new media workflow scripts, styles, and templates.
Please note that this commit does not integrate media into the existing UI. If you would like to see the new UI, navigate to the post editor and run the following in your browser's Javascript console:
new wp.media.controller.Workflow().render().modal.open();
The Javascript is broken up into two files, with the slugs media-models and media-views.
* media-models: The models are UI agnostic, and can be used independent of the views. If you'd like to create custom UIs, this is the script for you.
* media-views: This is the Media Experience. The views (and controllers) depend on the models (which are listed as a dependency and will automatically be included thanks to wp_enqueue_script). The views also require the media templates, media-view styles, and the plupload bridge settings. Perhaps we should create a function to include the whole shebang, but in the meantime...
To include media-views in the admin, run the following PHP in or after 'admin_enqueue_scripts':
wp_enqueue_script( 'media-views' );
wp_enqueue_style( 'media-views' );
wp_plupload_default_settings();
add_action( 'admin_footer', 'wp_print_media_templates' );
see #21390.
git-svn-id: http://core.svn.wordpress.org/trunk@21683 1a063a9b-81f0-0310-95a4-ce76da25c4cd
2012-08-31 06:54:23 +02:00
< ? php
}