Philipp, tudo é possível se você se dedicar a isso. Você pode resolver seu problema estendendo a classe do editor de imagens do WordPress.
Nota: estou usando o WordPress 3.7 - não verifiquei nenhum dos códigos abaixo nas versões anteriores e na versão 3.8 mais recente.
Noções básicas do Image Editor
O WordPress possui duas classes integradas que lidam com a manipulação de imagens:
WP_Image_Editor_GD
( /wp-includes/class-wp-image-editor-gd.php
)
WP_Image_Editor_Imagick
( /wp-includes/class-wp-image-editor-imagick.php
)
Essas duas classes se estendem WP_Image_Editor
porque ambas usam um mecanismo de imagem diferente (GD e ImageMagick, respectivamente) para carregar, redimensionar, compactar e salvar imagens.
Por padrão, o WordPress tentará usar o mecanismo ImageMagick primeiro, que precisa de uma extensão PHP, porque geralmente é preferível ao mecanismo GD padrão do PHP. A maioria dos servidores compartilhados não tem a extensão ImageMagick ativada.
Adicionar um editor de imagens
Para decidir qual mecanismo usar, o WordPress chama uma função interna __wp_image_editor_choose()
(localizada em /wp-includes/media.php
). Essa função percorre todos os mecanismos para ver qual mecanismo pode lidar com a solicitação.
A função também possui um filtro chamado wp_image_editors
que permite adicionar mais editores de imagem, 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;
}
Observe que estamos anexando nossa classe personalizada de editor de imagens WP_Image_Editor_Custom
para que o WordPress verifique se nosso mecanismo pode lidar com o redimensionamento antes de testar outros mecanismos.
Criando nosso Editor de Imagens
Agora vamos escrever nosso próprio editor de imagens para que possamos decidir os nomes dos arquivos. A nomeação de arquivos é tratada pelo método WP_Image_Editor::generate_filename()
(ambos os mecanismos herdam esse método), portanto, devemos substituí-lo em nossa classe personalizada.
Como planejamos apenas alterar os nomes de arquivos, devemos estender um dos mecanismos existentes para não precisar reinventar a roda. Vou estender WP_Image_Editor_GD
meu exemplo, pois você provavelmente não tem a extensão ImageMagick ativada. O código é intercambiável para uma configuração do ImageMagick. Você pode adicionar ambos se estiver planejando usar o tema em diferentes configurações.
// 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}";
}
}
A maior parte do código acima foi copiada diretamente da WP_Image_Editor
classe e comentada para sua conveniência. A única mudança real é que o sufixo agora é um prefixo.
Como alternativa, você pode simplesmente chamar parent::generate_filename()
e usar um mb_str_replace()
para mudar o sufixo para um prefixo, mas achei que seria mais provável que desse errado.
Salvando Novos Caminhos para Metadados
Após o upload image.jpg
, a pasta de uploads fica assim:
2013/12/150x150/image.jpg
2013/12/300x300/image.jpg
2013/12/image.jpg
Por enquanto, tudo bem. No entanto, ao chamar funções básicas como wp_get_attachment_image_src()
, notamos que todos os tamanhos de imagem são armazenados como image.jpg
sem o novo caminho do diretório.
Podemos solucionar esse problema salvando a nova estrutura de pastas nos metadados da imagem (onde os nomes dos arquivos estão armazenados). Os dados executado através de vários filtros ( wp_generate_attachment_metadata
entre outros), antes de ser inserido no banco de dados, mas uma vez que já está implementando um editor de imagem personalizada, podemos viajar de volta para a fonte de tamanho da imagem metadados: WP_Image_Editor::multi_resize()
. Ele gera matrizes 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
)
)
Sobrescreveremos o multi_resize()
método em nossa classe 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 você pode ver, eu não me incomodei em substituir nenhum código. Eu apenas chamo o método pai e deixo gerar os metadados. Em seguida, percorro a matriz resultante e ajusto o file
valor para cada tamanho.
Agora wp_get_attachment_image_src($att_id, array(300, 300))
retorna 2013/12/300x300/image.jpg
. Viva!
Pensamentos finais
Espero que isso tenha fornecido uma boa base para você elaborar. No entanto, observe se uma imagem é menor que o tamanho especificado (por exemplo, 280x300), o sufixo gerado (prefixo no nosso caso) e os tamanhos de imagem são 280x300, não 300x300. Se você enviar muitas imagens menores, terá muitas pastas diferentes.
Uma boa solução seria usar o tamanho slug como um nome de pasta ( small
, medium
etc.) ou expandir o código para tamanhos redondos até o tamanho de imagem preferido mais próximo.
Você notou que deseja usar apenas a largura como um nome de diretório. Esteja avisado - plugins ou temas podem gerar dois tamanhos diferentes com a mesma largura, mas com alturas diferentes.
Além disso, você pode remover as pastas de ano / mês desabilitando 'Organizar meus envios em pastas baseadas em mês e ano' em Configurações> Mídia ou manipulando generate_filename
ainda mais.
Espero que isto ajude. Boa sorte!
A resposta de @ Robbert foi um recurso divino em meus esforços para armazenar tamanhos alternativos gerados pelo WordPress em diretórios separados. Meu código também altera o diretório de upload para ./media, portanto, certifique-se de editar essas linhas, se você não quiser. Não é uma resposta exata para a pergunta do primeiro pôster, mas oferece uma solução alternativa para o mesmo problema:
Funciona sem problemas de acordo com meus testes, embora eu não tenha tentado verificar como ele se sai com os populares plugins de galeria / mídia.
bônus relacionado: um utilitário bruto para excluir todas as miniaturas geradas pelo WordPress delete_deprecated_thumbs.php
fonte
Examinei essas partes do código do WordPress e tenho medo de não ter boas notícias.
Existem 2 classes:
WP_Image_Editor_GD
WP_Image_Editor_Imagick
,ambos estendendo a
WP_Image_Editor
classe abstrata .Essas classes estão implementando o
multi_resize
método, usado para gerar várias imagens a partir de uma carregada.A notícia realmente ruim é que não há ganchos de filtro, que poderíamos usar para modificar o caminho de destino para arquivos recém-criados.
fonte
noscript
tag)<img src="http://placehold.it/260" data-src="http://placehold.it/{width}" />
. E então o script verifica qual o tamanho do img e carrega o melhor tamanho de imagem para isso.Ok, acho que entendi! Não é perfeito, mas tudo bem para isso que eu queria. Para mim, apenas a largura de uma imagem é importante. Altura é inútil para mim. Especialmente para implementar o Imager.js, a altura no URL da imagem é perturbadora.
Com esse código, os nomes de arquivos são como:
É não possível adicionar uma subpasta para os nomes dos arquivos, porque se eu adicionar imagens em um post / página sempre a fonte original será usado. E remover essas imagens ao excluir também não funcionará. Não sei por que.
fonte