✅ Notícias, temas e plug-ins da WEB e do WordPress. Aqui compartilhamos dicas e as melhores soluções para sites.

Modificar contêineres de imagem no lado do servidor no WordPress

30

Sempre que você estiver criando soluções personalizadas para outras pessoas, poderá ter que lidar com casos sutis de como o WordPress está renderizando o conteúdo.

Isso geralmente se resume ao tema, pelo menos um plugin ou a combinação de ambos. E se você precisar trabalhar com imagens individualmente, pode ser um desafio. O problema de até mesmo tentar escrever um post como esse é que é difícil até mesmo descrever uma situação em que você possa precisar de algo assim.

Mesmo assim, vou fazer o melhor que posso. Ou seja, quero compartilhar como modificar contêineres de imagem no lado do servidor antes de renderizá-los no lado do cliente e fazê-lo usando a biblioteca DOMDocument do PHP.

Parece muito? Espero que eu possa quebrar isso com bastante facilidade.

Antes de entrar no código, digamos que você tenha um them que renderize imagens em um único elemento de parágrafo (ou qualquer tipo de elemento em nível de bloco) e você precise envolver cada elemento em algum tipo de classe para poder acessar via CSS ou JavaScript.

Onde estamos

Então, para começar, digamos que as imagens sejam renderizadas assim:

E você precisa renderizá-los assim:

Modificar contêineres de imagem no lado do servidor no WordPress

Agora, você pode ou não precisar de espaço entre eles. Isso realmente não importa porque você tem controle sobre isso via CSS. Mas você tem controle sobre como isso é enviado pela rede para o lado do cliente.

Para fazer isso, você precisa de algumas coisas:

  • Acesso à biblioteca DOMDocument do PHP,
  • Compreensão de como manipular conteúdo através do gancho the_content do WordPress,
  • Uma estratégia de como você deseja envolver as imagens.

Vou percorrer cada uma delas no código, mas basta dizer que vou envolver cada imagem em um elemento de parágrafo. Obviamente, você pode optar por fazer o que quiser.

Como fazer isso

Primeiro, certifique-se de ter declarado que está usando o conteúdo do documento DOM acima de sua classe :

<?php

namespace Acme;

use DOMDocument;

class AcmeContentSubscriber
{
  // ...
}

Em seguida, vá em frente e crie um gancho para the_content. Como você faz isso dependerá de como você organizou seu código (seja OOP ou não). Para este exemplo, vou mostrar um exemplo muito simples de como fazer isso :

<?php

public function contentSubscriber()
{
  add_action( 'the_content', [$this, 'addImageAttributes']);
}

Depois disso, você precisará fazer um pouco de trabalho (tudo o que está abaixo, mas fora do escopo deste post). Isso inclui:

  • convertendo a codificação das entidades HTML,
  • criando uma instância do documento DOM,
  • carregando o HTML da postagem do conteúdo recebido

No código, deve ficar assim :

<?php

public function addImageAttributes($content)
{

    $content  = mb_convert_encoding($content, 'HTML-ENTITIES', "UTF-8");
    $document = new DOMDocument();

    libxml_use_internal_errors(true);
    $document->loadHTML(utf8_decode($content));

    // ...
}

Em seguida, você precisa percorrer os  elementos img e certificar-se de que está configurando um atributo adequado. Você pode optar por usar uma classe, pode optar por usar um atributo de dados ou pode optar por usar outra coisa. Essa parte não importa.

Observe que, para uma determinada imagem, você desejará verificar se o próximo elemento não é um elemento de parágrafo, pois é isso que estou optando por envolver a imagem. Em outras palavras, se o próximo elemento não for um parágrafo, envolveremos o elemento em um elemento de parágrafo.

Para fazer isso, o esqueleto da função principal deve ficar assim :

<?php

public function addImageAttributes($content)
{

    $content  = mb_convert_encoding($content, 'HTML-ENTITIES', "UTF-8");
    $document = new DOMDocument();

    libxml_use_internal_errors(true);
    $document->loadHTML(utf8_decode($content));

    $images = $document->getElementsByTagName('img');
    foreach ($images as $image) {
        $image->setAttribute('class', 'acme-iamge');
        if ($image->nextSibling->tagName !== 'p') {
            $this->wrapImage($document, $image);
        }
    }

    // ...
}

Então a função responsável por realmente envolver o elemento em um elemento de parágrafo deve ficar assim :

<?php

/**
 * This function is used to wrap individual images in a paragraph element.
 *
 * @param $document The DOM Document which is to be rendered.
 * @param $image    The image to wrap with the new paragraph element.
 */
private function wrapImage($document, $image)
{
    if (null === $image) {
        return;
    }
    $wrapper = $document->createElement('p');
    $wrapper->setAttribute('class', 'acme-image');

    $image->parentNode->replaceChild($wrapper, $image);
    if (null !== $image) {
        $wrapper->appendChild($image);
    }
}

Certifique-se de ler o DocBlock do código para entender como a função funciona. Basta colocar:

  • ele aceita uma instância do documento e o elemento de imagem,
  • cria um elemento de parágrafo,
  • adiciona um atributo de classe
  • substitui o elemento da imagem original pelo parágrafo,
  • e adiciona a imagem como um elemento filho

E como baseamos o objeto de documento no método, não precisamos retornar nada.

A versão final da função original deve ficar assim :

<?php

public function addImageAttributes($content)
{

    $content  = mb_convert_encoding($content, 'HTML-ENTITIES', "UTF-8");
    $document = new DOMDocument();

    libxml_use_internal_errors(true);
    $document->loadHTML(utf8_decode($content));

    $images = $document->getElementsByTagName('img');
    foreach ($images as $image) {
        $image->setAttribute('class', 'acme-image');
        if ($image->nextSibling->tagName !== 'p') {
            $this->wrapImage($document, $image);
        }
    }

  return $document->saveHTML();
}

E sua saída deve se parecer com a imagem acima. Lembre-se, porém; você precisa retornar os resultados da instância do documento para o WordPress, para que ele renderize corretamente o HTML. E é isso que a  função saveHTML está fazendo no código acima.

Fonte de gravação: tommcfarlin.com

Este site usa cookies para melhorar sua experiência. Presumiremos que você está ok com isso, mas você pode cancelar, se desejar. Aceitar Consulte Mais informação