答案“robbert”是一个非常棒的答案。然而,它有点过时(我使用的是WordPress 5.7),我想做完全相同的事情,所以这里有一个稍微更新的答案,附带一些额外内容:
我使用了段塞大小而不是尺寸,因为这有点干净,我想从@robert代码中演示一下一个额外的过滤器,用于更新post meta。这样,您以后也可以从媒体库中删除图像。否则,缩略图将留在文件系统中为了完成,我添加了GD和Imagick类扩展我将它们作为插件放在同一个文件中。
添加两个新编辑器
/**
* Add custom image editor (which extends the GD / IMagick editor)
*/
add_filter("wp_image_editors", "my_wp_image_editors");
function my_wp_image_editors($editors) {
array_unshift($editors, "WP_Image_Editor_Custom_GD");
array_unshift($editors, "WP_Image_Editor_Custom_IM");
return $editors;
}
GD类扩展
/**
* If GD Library being used. (default)
*/
class WP_Image_Editor_Custom_GD extends WP_Image_Editor_GD {
/**
* Add the folder prefix before saving to the database and generating
*/
function multi_resize($sizes) {
$sizes = parent::multi_resize($sizes);
foreach($sizes as $slug => $data)
// $sizes[$slug][\'file\'] = $data[\'width\']."x".$data[\'height\']."/".$data[\'file\']; // creates a /320x300/ folder.
$sizes[$slug][\'file\'] = $slug."/".$data[\'file\']; // creates a /large/ folder.
return $sizes;
}
/**
* Changes the suffix (300x300) to a directory prefix.
*/
public function generate_filename($prefix = NULL, $dest_path = NULL, $extension = NULL) {
// If empty, generate a prefix with the parent method get_suffix().
if(!$prefix)
$prefix = $this->get_suffix();
// Determine extension and directory based on file path.
$info = pathinfo($this->file);
$dir = $info[\'dirname\'];
$ext = $info[\'extension\'];
$sizes = wp_get_registered_image_subsizes();
$dimen = explode(\'x\', $prefix);
foreach($sizes as $name => $size)
{
if ($dimen[0] == $size[\'width\']){
$prefix = $name;
}
}
// Determine image name.
$name = wp_basename($this->file, ".$ext");
// Allow extension to be changed via method argument.
$new_ext = strtolower($extension ? $extension : $ext);
// Default to $_dest_path if method argument is not set or invalid.
if(!is_null($dest_path) && $_dest_path = realpath($dest_path))
$dir = $_dest_path;
// Return our new prefixed filename.
return trailingslashit($dir)."{$prefix}/{$name}.{$new_ext}";
}
}
IMagick类扩展
/**
* If Imagemagick is being used.
*/
class WP_Image_Editor_Custom_IM extends WP_Image_Editor_Imagick {
/**
* Add the folder prefix before saving to the database and generating
*/
function multi_resize($sizes) {
$sizes = parent::multi_resize($sizes);
foreach($sizes as $slug => $data)
// $sizes[$slug][\'file\'] = $data[\'width\']."x".$data[\'height\']."/".$data[\'file\']; // creates a /320x300/ folder.
$sizes[$slug][\'file\'] = $slug."/".$data[\'file\']; // creates a /large/ folder.
return $sizes;
}
/**
* Changes the suffix (300x300) to a directory prefix.
*/
public function generate_filename($prefix = NULL, $dest_path = NULL, $extension = NULL) {
// If empty, generate a prefix with the parent method get_suffix().
if(!$prefix)
$prefix = $this->get_suffix();
$sizes = wp_get_registered_image_subsizes();
$dimen = explode(\'x\', $prefix);
foreach($sizes as $name => $size)
{
if ($dimen[0] == $size[\'width\']){
$prefix = $name;
}
}
// Determine extension and directory based on file path.
$info = pathinfo($this->file);
$dir = $info[\'dirname\'];
$ext = $info[\'extension\'];
// Determine image name.
$name = wp_basename($this->file, ".$ext");
// Allow extension to be changed via method argument.
$new_ext = strtolower($extension ? $extension : $ext);
// Default to $_dest_path if method argument is not set or invalid.
if(!is_null($dest_path) && $_dest_path = realpath($dest_path))
$dir = $_dest_path;
// Return our new prefixed filename.
return trailingslashit($dir)."{$prefix}/{$name}.{$new_ext}";
}
}
更新附件元数据
/**
* We need to rewrite the post attachment metadata so that
* we include the new /slug/ directory. This is so we are able to
* delete / edit the thumbnail correctly.
*
* see function wp_get_attachment_metadata() in wp-include/post.php
*
*/
add_filter(\'wp_get_attachment_metadata\', \'include_slug_in_attachment_size\', 10, 2);
function include_slug_in_attachment_size($data, $attachment_id)
{
// Add the size slug to the front of the filename.
foreach($data[\'sizes\'] as $name => $size)
{
$file = $data[\'sizes\'][$name][\'file\'];
$data[\'sizes\'][$name][\'file\'] = $name .\'/\'.$file;
}
return $data;
}
现在,将在uploads文件夹中创建具有媒体大小名称的子目录,例如。
/uploads/photo.jpg
将会有
/uploads/thumbnail/photo.jpg
,
/uploads/medium/photo.jpg
, 等但不仅如此,删除也会删除这些附件。(另外,如果文件夹变为空,也将被删除)。
详细信息-无需阅读。对于好奇的人,删除流程如下:
post.php
将运行wp_delete_attachment()
功能- 该函数将运行以下行:
$meta = wp_get_attachment_metadata( $post_id );
- 的
wp_get_attachment_metadata
中的函数post.php
将运行wp_get_attachment_metadata
过滤器它将运行我们的自定义筛选函数(上面声明),该函数将在$data[\'sizes\']
数组并将其返回那个新的$data
数组传回集合$meta
在里面wp_delete_attachment()
. $meta
然后在wp_delete_attachment()
函数,在线:
wp_delete_attachment_files( $post_id, $meta, $backup_sizes, $file );
wp_delete_attachment_files()
函数将使用此$meta
带有foreach()
循环遍历大小并删除每个文件名(我们将其更新为包含slug目录)
// Remove intermediate and backup images if there are any.
if ( isset( $meta[\'sizes\'] ) && is_array( $meta[\'sizes\'] ) ) {
$intermediate_dir = path_join( $uploadpath[\'basedir\'], dirname( $file ) );
foreach ( $meta[\'sizes\'] as $size => $sizeinfo ) {
$intermediate_file = str_replace( wp_basename( $file ), $sizeinfo[\'file\'], $file );
if ( ! empty( $intermediate_file ) ) {
$intermediate_file = path_join( $uploadpath[\'basedir\'], $intermediate_file );
if ( ! wp_delete_file_from_directory( $intermediate_file, $intermediate_dir ) ) {
$deleted = false;
}
}
}
}
就这样。这将看到更新的
$sizes
阵列(在
$meta
) 更新日期:
\'sizes =>
\'large\' =>
[
\'file\' => \'photo.jpg\',
\'width\' => \'800\',
\'height\' => \'800\',
\'mimetype\' => \'image/jpeg\',
],
\'medium\' =>
[
\'file\' => \'photo.jpg\',
\'width\' => \'640\',
\'height\' => \'640\',
\'mimetype\' => \'image/jpeg\',
],
...
成为:
\'sizes =>
\'large\' =>
[
\'file\' => \'large/photo.jpg\',
\'width\' => \'800\',
\'height\' => \'800\',
\'mimetype\' => \'image/jpeg\',
],
\'medium\' =>
[
\'file\' => \'medium/photo.jpg\',
\'width\' => \'640\',
\'height\' => \'640\',
\'mimetype\' => \'image/jpeg\',
],
...