Philipp, tutto è possibile se ci pensi. Puoi risolvere il tuo problema estendendo la classe dell'editor di immagini di WordPress.
Nota Sto usando WordPress 3.7 - Non ho controllato nessuno dei codici seguenti nelle versioni precedenti e nell'ultima versione 3.8.
Nozioni di base di Image Editor
WordPress ha due classi integrate che gestiscono la manipolazione delle immagini:
WP_Image_Editor_GD
( /wp-includes/class-wp-image-editor-gd.php
)
WP_Image_Editor_Imagick
( /wp-includes/class-wp-image-editor-imagick.php
)
Queste due classi si estendono WP_Image_Editor
perché utilizzano entrambe un motore di immagine diverso (rispettivamente GD e ImageMagick) per caricare, ridimensionare, comprimere e salvare le immagini.
Per impostazione predefinita, WordPress proverà a utilizzare prima il motore ImageMagick, che necessita di un'estensione PHP, perché è generalmente preferito al motore GD predefinito di PHP. La maggior parte dei server condivisi non ha l'estensione ImageMagick abilitata però.
Aggiungi un editor di immagini
Per decidere quale motore utilizzare, WordPress chiama una funzione interna __wp_image_editor_choose()
(situata in /wp-includes/media.php
). Questa funzione scorre in tutti i motori per vedere quale motore può gestire la richiesta.
La funzione ha anche un filtro chiamato wp_image_editors
che ti consente di aggiungere altri editor di immagini in questo modo:
add_filter("wp_image_editors", "my_wp_image_editors");
function my_wp_image_editors($editors) {
array_unshift($editors, "WP_Image_Editor_Custom");
return $editors;
}
Nota che stiamo anteponendo la nostra classe di editor di immagini personalizzata in WP_Image_Editor_Custom
modo che WordPress controllerà se il nostro motore può gestire il ridimensionamento prima di testare altri motori.
Creazione del nostro editor di immagini
Ora scriveremo il nostro editor di immagini in modo da poter decidere da soli i nomi dei file. Il nome del file è gestito dal metodo WP_Image_Editor::generate_filename()
(entrambi i motori ereditano questo metodo), quindi dovremmo sovrascriverlo nella nostra classe personalizzata.
Poiché prevediamo solo di cambiare i nomi dei file, dovremmo estendere uno dei motori esistenti in modo da non dover reinventare la ruota. Estenderò WP_Image_Editor_GD
nel mio esempio, poiché probabilmente non hai abilitato l'estensione ImageMagick. Tuttavia, il codice è intercambiabile per una configurazione di ImageMagick. È possibile aggiungere entrambi se si prevede di utilizzare il tema su diverse configurazioni.
// 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 maggior parte del codice sopra è stato copiato direttamente dalla WP_Image_Editor
classe e commentato per tua comodità. L'unica modifica effettiva è che il suffisso è ora un prefisso.
In alternativa, potresti semplicemente chiamare parent::generate_filename()
e usare un mb_str_replace()
per cambiare il suffisso in un prefisso, ma ho pensato che sarebbe stato più propenso a sbagliare.
Salvataggio di nuovi percorsi per i metadati
Dopo il caricamento image.jpg
, la cartella dei caricamenti è simile alla seguente:
2013/12/150x150/image.jpg
2013/12/300x300/image.jpg
2013/12/image.jpg
Fin qui tutto bene. Tuttavia, quando si chiamano funzioni di base come wp_get_attachment_image_src()
, noteremo che tutte le dimensioni dell'immagine sono memorizzate come image.jpg
senza il nuovo percorso della directory.
Possiamo aggirare questo problema salvando la nuova struttura di cartelle nei metadati dell'immagine (dove sono memorizzati i nomi dei file). Le piste di dati attraverso i vari filtri ( wp_generate_attachment_metadata
tra gli altri) prima di essere inseriti nel database, ma dal momento che stiamo già implementando un editor di immagini su misura, siamo in grado di tornare indietro alla fonte dei metadati dimensioni dell'immagine: WP_Image_Editor::multi_resize()
. Genera array come questo:
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
)
)
Sovrascriveremo il multi_resize()
metodo nella nostra classe personalizzata:
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;
}
Come puoi vedere, non mi sono preoccupato di sostituire alcun codice. Chiamo solo il metodo parent e lascio che generi i metadati. Quindi eseguo il ciclo attraverso l'array risultante e modifico il file
valore per ogni dimensione.
Ora wp_get_attachment_image_src($att_id, array(300, 300))
ritorna 2013/12/300x300/image.jpg
. Evviva!
Pensieri finali
Spero che questo abbia fornito una buona base per approfondire. Tuttavia, si noti che se un'immagine è più piccola della dimensione specificata (ad es. 280x300), il suffisso generato (prefisso nel nostro caso) e le dimensioni dell'immagine sono 280x300, non 300x300. Se carichi molte immagini più piccole, otterrai molte cartelle diverse.
Una buona soluzione sarebbe o utilizzare per lo spezzone formato come un nome di cartella ( small
, medium
, eccetera) o espandere il codice a dimensioni tondi fino alla dimensione dell'immagine preferita vicina.
Hai notato che vuoi usare solo la larghezza come nome di directory. Attenzione però: plugin o temi potrebbero generare due dimensioni diverse con la stessa larghezza ma altezze diverse.
Inoltre, puoi rimuovere le cartelle anno / mese disabilitando "Organizza i miei caricamenti in cartelle basate su mese e anno" in Impostazioni> Media o manipolando generate_filename
ulteriormente.
Spero che questo ti aiuti. In bocca al lupo!