Philipp, todo es posible si te lo propones. Puede resolver su problema extendiendo la clase de editor de imágenes de WordPress.
Nota que estoy usando WordPress 3.7: no he comprobado ninguno de los códigos a continuación en versiones anteriores y en la última versión 3.8.
Conceptos básicos del editor de imágenes
WordPress tiene dos clases integradas que manejan la manipulación de imágenes:
-
WP_Image_Editor_GD
( /wp-includes/class-wp-image-editor-gd.php
)
-
WP_Image_Editor_Imagick
( /wp-includes/class-wp-image-editor-imagick.php
)
Estas dos clases extienden WP_Image_Editor
porque ambas usan un motor de imagen diferente (GD e ImageMagick respectivamente) para cargar, redimensionar, comprimir y guardar imágenes.
Por defecto, WordPress intentará usar el motor ImageMagick primero, que necesita una extensión de PHP, ya que generalmente se prefiere al motor GD predeterminado de PHP. Sin embargo, la mayoría de los servidores compartidos no tienen habilitada la extensión ImageMagick.
Añadir un editor de imágenes
Para decidir qué motor usar, WordPress llama a una función interna __wp_image_editor_choose()
(ubicada en /wp-includes/media.php
). Esta función recorre todos los motores para ver qué motor puede manejar la solicitud.
La función también tiene un filtro llamado wp_image_editors
que le permite agregar más editores de imágenes como:
add_filter("wp_image_editors", "my_wp_image_editors");
function my_wp_image_editors($editors) {
array_unshift($editors, "WP_Image_Editor_Custom");
return $editors;
}
Tenga en cuenta que estamos preparando nuestra clase personalizada de editor de imágenes WP_Image_Editor_Custom
para que WordPress verifique si nuestro motor puede manejar el cambio de tamaño antes de probar otros motores.
Creando nuestro editor de imágenes
Ahora vamos a escribir nuestro propio editor de imágenes para que podamos decidir los nombres de los archivos por nosotros mismos. El nombre de archivo se maneja con el método WP_Image_Editor::generate_filename()
(ambos motores heredan este método), por lo que deberíamos sobrescribirlo en nuestra clase personalizada.
Ya que solo planeamos cambiar los nombres de archivos, deberíamos ampliar uno de los motores existentes para que no tengamos que reinventar la rueda. Extenderé WP_Image_Editor_GD
en mi ejemplo, ya que probablemente no tenga habilitada la extensión ImageMagick. El código es intercambiable para una configuración de ImageMagick sin embargo. Puede agregar ambos si planea usar el tema en diferentes configuraciones.
// Include the existing classes first in order to extend them.
require_once ABSPATH.WPINC."/class-wp-image-editor.php";
require_once ABSPATH.WPINC."/class-wp-image-editor-gd.php";
class WP_Image_Editor_Custom extends WP_Image_Editor_GD {
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'];
// 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}";
}
}
La mayoría del código anterior se copió directamente de la clase WP_Image_Editor
y se comentó para su conveniencia. El único cambio real es que el sufijo ahora es un prefijo.
Alternativamente, puedes llamar a parent::generate_filename()
y usar un mb_str_replace()
para cambiar el sufijo a un prefijo, pero pensé que sería más propenso a salir mal.
Guardando nuevas rutas a metadatos
Después de cargar image.jpg
, la carpeta de subidas se ve así:
-
2013/12/150x150/image.jpg
-
2013/12/300x300/image.jpg
-
2013/12/image.jpg
Hasta ahora todo bien. Sin embargo, al llamar a funciones básicas como wp_get_attachment_image_src()
, notaremos que todos los tamaños de imagen se almacenan como image.jpg
sin la nueva ruta del directorio.
Podemos solucionar este problema guardando la nueva estructura de carpetas en los metadatos de la imagen (donde se almacenan los nombres de archivo). Los datos se ejecutan a través de varios filtros ( wp_generate_attachment_metadata
entre otros) antes de ser insertados en la base de datos, pero como ya estamos implementando un editor de imágenes personalizado, podemos regresar a la fuente de metadatos de tamaño de imagen: WP_Image_Editor::multi_resize()
. Genera matrices como esta:
Array (
[thumbnail] => Array (
[file] => image.jpg
[width] => 150
[height] => 150
[mime-type] => image/jpeg
)
[medium] => Array (
[file] => image.jpg
[width] => 300
[height] => 300
[mime-type] => image/jpeg
)
)
Sobrescribiremos el método multi_resize()
en nuestra clase personalizada:
function multi_resize($sizes) {
$sizes = parent::multi_resize($sizes);
foreach($sizes as $slug => $data)
$sizes[$slug]['file'] = $data['width']."x".$data['height']."/".$data['file'];
return $sizes;
}
Como puedes ver, no me molesté en reemplazar ninguno de los códigos. Acabo de llamar al método principal y dejo que genere los metadatos. Luego recorro la matriz resultante y ajusto el valor file
para cada tamaño.
Ahora wp_get_attachment_image_src($att_id, array(300, 300))
devuelve 2013/12/300x300/image.jpg
. ¡Hurra!
Pensamientos finales
Espero que esto te haya brindado una buena base para que lo expliques. Sin embargo, tenga en cuenta si una imagen es más pequeña que el tamaño especificado (por ejemplo, 280x300), el sufijo generado (prefijo en nuestro caso) y los tamaños de imagen son 280x300, no 300x300. Si subes muchas imágenes más pequeñas, obtendrás muchas carpetas diferentes.
Una buena solución sería usar la barra de tamaño como nombre de carpeta ( small
, medium
, etc.) o expandir el código a tamaños redondos hasta el tamaño de imagen preferido más cercano.
Notaste que querías usar solo el ancho como un nombre de directorio. Sin embargo, tenga cuidado: los complementos o temas pueden generar dos tamaños diferentes con el mismo ancho pero diferentes alturas.
Además, puede eliminar las carpetas de año / mes ya sea deshabilitando "Organizar mis cargas en carpetas basadas en el mes y el año" en Configuración > Medios o manipulando generate_filename
aún más.
Espero que esto ayude. Buena suerte!