Neste tutorial, aprenderemos como criar um widget personalizado que gera as informações da sua empresa, como nome oficial, endereço, número de telefone e e-mail. Mas daremos um passo adiante, exibindo-o com microdados ou marcação de esquema, o que permitirá que os mecanismos de pesquisa entendam seu conteúdo.
Widgets são blocos dinâmicos que podem ser colocados em áreas disponíveis em seu tema. Normalmente seu tema teria no mínimo uma barra lateral e uma ou mais áreas no rodapé. Ter as informações do seu negócio como um widget no rodapé é comum e bastante inteligente – já que o rodapé aparece em todas as páginas do seu site.
Microdados são atributos HTML adicionais que explicam o que a tag HTML específica contém para que uma máquina possa entender o que são (por exemplo, nome comercial, número de telefone, endereço comercial, endereço de e-mail comercial etc.). Isso possibilita que mecanismos de pesquisa, como o Google, extraiam informações sobre sua empresa de seu HTML.
O que vamos criar
Nosso widget produzirá informações usando o esquema de microdados LocalBusiness, que é perfeito para uma organização ou negócio. Cabe a você decidir quais propriedades você deseja produzir, basta clicar no link acima para ler todas as propriedades possíveis no LocalBusiness (incluindo herdadas). Sua empresa ou seu país podem preferir tipos diferentes de informações.
O widget deste tutorial produzirá as seguintes informações opcionais:
- Nome da empresa (propriedade de microdados:
legalName) - ID do IVA ou número da organização (propriedade Microdata:
vatID) - Endereço postal (tag Microdata:
PostalAddresscom propriedades parastreetAddress,postalCodeeaddressLocality) - Endereço de e-mail da empresa (propriedade Microdata:
email) - Número de telefone (propriedade de microdados:
telephone)
Este tutorial não o guiará pelo estilo do widget, pois isso deve ser bastante simples. No frontend nosso widget se parecerá com um widget de texto normal. Mas é claro que, sob o capô, ele possui marcação de esquema que ajuda o Google.
Noções básicas de criação de um widget personalizado
Você pode colocar seu código no seu tema functions.phpou criar um plugin personalizado. Apenas lembre-se que se você mantê-lo em um plugin, você perderá o widget ao desativá-lo; e, da mesma forma, mantê-lo no tema fará com que você perca o widget se alternar para outro tema. Neste exemplo, adicionarei o código no arquivo functions.php.
A criação de um widget é feita com código PHP orientado a objetos. Você escreve uma classe PHP que estende a classe de widget do WordPress e a inicializa chamando register_widget()e fornecendo o nome da sua classe. Neste tutorial eu nomeei minha classe de widget LocalBusiness.
Vamos começar chamando register_widget()dentro de uma função ligada à ação widgets_init.
add_action('widgets_init', function() {
register_widget('LocalBusiness');
});
Vamos examinar rapidamente o esqueleto de uma classe de widget personalizada:
class LocalBusiness extends WP_Widget {
// Initialize your widget in the class constructor
public function __construct() { }
// Responsible for outputting the widget in frontend
public function widget($args, $instance) { }
// Responsible for outputting the widget settings in admin
public function form($instance) { }
// Responsible for saving settings in admin
public function update($new_instance, $old_instance) { }
}
Como você pode ver acima, você precisará de quatro funções dentro de sua classe. Vamos passar por cada função uma por uma e preenchê-las.
Criando um widget de microdados do LocalBusiness
O lugar mais lógico para começar é no construtor, que é responsável por configurar seu widget.
A função __construct()
Dentro do construtor você precisa configurar algumas variáveis, como o nome do widget, e chamar a função construtora do pai (a classe pai é aquela que você estende; WP_Widget). Leia mais sobre as opções possíveis no construtor aqui. Vou fornecer um ID base, um título e uma descrição, assim:
// Initialize your widget in the class constructor
public function __construct() {
$widget_ops = [
'description' => __('Outputs business information with Microdata', 'txtdomain')
];
parent::__construct('local_business', __('Local Business Information', 'txtdomain'), $widget_ops);
}
Você pode fazer mais no __constructmétodo, como enfileirar scripts ou definir mais configurações de widget. Mas o acima geralmente é suficiente na maioria dos casos.
A função form()
O próximo passo é construir todas as configurações e entradas que seu widget aceita no admin. Para as configurações de saída para o administrador do Widget, usamos a função form()que fornece um parâmetro; uma matriz que contém todas as suas opções de widget possivelmente salvas. É importante que você emita a configuração salva correspondente em todas as suas entradas para que os dados sejam retidos. (Veremos como salvar as configurações na próxima etapa).
Há muito para acompanhar na função de formulário, então vamos apenas adicionar uma entrada, para o nome legal, primeiro e ter certeza de que entendemos o que precisamos fazer:
// Responsible for outputting the widget settings in admin
public function form($instance) {
?>
<p>
<label for="<?php echo $this->get_field_id('legal_name'); ?>"><?php _e('Legal name:', 'txtdomain'); ?></label>
<input
type="text"
class="widefat"
id="<?php echo esc_attr($this->get_field_id('legal_name')); ?>"
name="<?php echo esc_attr($this->get_field_name('legal_name')); ?>"
value="<?php echo esc_attr($instance['legal_name']); ?>"
/>
</p>
<?php
}
Em primeiro lugar, o código acima gera alguns wrappers e classes HTML na forma em que o WordPress gera seus formulários de widget – fazemos isso para que o formulário pareça bom.
Existem duas funções com as quais você precisa se familiarizar; get_field_id()e get_field_name()ambos são funções dentro WP_Widget(e é por isso que você chama ” $this->" na frente – enquanto $thisse refere à instância da classe). As funções retornam o ID e o nome de um campo fornecido, respectivamente, para uso em suas entradas ide nameatributos. É muito importante para não esquecer de adicionar um nameatributo em sua entrada, caso contrário, você nunca obterá seu valor ao salvar.
E finalmente nós produzimos o valor salvo atual como valuenossa entrada referenciando o argumento passado $instance. Sem fazer isso para o seu valor, a entrada nunca será preenchida com o que está salvo no banco de dados e aparecerá em branco todas as vezes, o que pode confundir os usuários.
Se você quiser entradas de formulário diferentes, como caixas de seleção ou menus suspensos, poderá adicioná-los facilmente seguindo as regras mencionadas acima. Vamos adicionar o restante de nossas configurações de widget. Eles são todos entradas de texto, então é o mesmo código acima repetido, exceto seus IDs de campo. Nosso form()método acaba ficando assim:
// Responsible for outputting the widget settings in admin
public function form($instance) {
?>
<p>
<label for="<?php echo $this->get_field_id('legal_name'); ?>"><?php _e('Legal name:', 'txtdomain'); ?></label>
<input type="text" class="widefat" id="<?php echo esc_attr($this->get_field_id('legal_name')); ?>" name="<?php echo esc_attr($this->get_field_name('legal_name')); ?>" value="<?php echo esc_attr($instance['legal_name']); ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id('vat_id'); ?>"><?php _e('Vat ID/Organization number:', 'txtdomain'); ?></label>
<input type="text" class="widefat" id="<?php echo esc_attr($this->get_field_id('vat_id')); ?>" name="<?php echo esc_attr($this->get_field_name('vat_id')); ?>" value="<?php echo esc_attr($instance['vat_id']); ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id('street_address'); ?>"><?php _e('Street address:', 'txtdomain'); ?></label>
<input type="text" class="widefat" id="<?php echo esc_attr($this->get_field_id('street_address')); ?>" name="<?php echo esc_attr($this->get_field_name('street_address')); ?>" value="<?php echo esc_attr($instance['street_address']); ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id('postal_code'); ?>"><?php _e('Postal code:', 'txtdomain'); ?></label>
<input type="text" class="widefat" id="<?php echo esc_attr($this->get_field_id('postal_code')); ?>" name="<?php echo esc_attr($this->get_field_name('postal_code')); ?>" value="<?php echo esc_attr($instance['postal_code']); ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id('postal_city'); ?>"><?php _e('City:', 'txtdomain'); ?></label>
<input type="text" class="widefat" id="<?php echo esc_attr($this->get_field_id('postal_city')); ?>" name="<?php echo esc_attr($this->get_field_name('postal_city')); ?>" value="<?php echo esc_attr($instance['postal_city']); ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id('email_address'); ?>"><?php _e('E-mail address:', 'txtdomain'); ?></label>
<input type="text" class="widefat" id="<?php echo esc_attr($this->get_field_id('email_address')); ?>" name="<?php echo esc_attr($this->get_field_name('email_address')); ?>" value="<?php echo esc_attr($instance['email_address']); ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id('phone_number'); ?>"><?php _e('Phone number:', 'txtdomain'); ?></label>
<input type="text" class="widefat" id="<?php echo esc_attr($this->get_field_id('phone_number')); ?>" name="<?php echo esc_attr($this->get_field_name('phone_number')); ?>" value="<?php echo esc_attr($instance['phone_number']); ?>" />
</p>
<?php
}
Se você adicionar seu widget em uma área de widget disponível, ele deverá ficar assim:
A função atualizar()
A update()função é responsável por realmente salvar seus valores inseridos em admin. Infelizmente o WordPress não está fazendo isso automaticamente para você. São fornecidos nesta função dois parâmetros; geralmente chamado $new_instancee $old_instance. Dentro do primeiro parâmetro, $new_instance, você encontrará todos os valores que foram enviados e, no segundo, $old_instance, você encontrará os valores que estão atualmente salvos no banco de dados. Isso permite que você faça algumas comparações inteligentes, se necessário.
Normalmente, você simplesmente faria uma nova matriz de todas as configurações do seu widget e salvaria tudo o que está definido dentro do arquivo $new_instance. Também cuidamos de algumas higienização. Por fim, simplesmente retornamos este array, que informará ao WordPress o que salvar.
// Responsible for saving settings in admin
public function update($new_instance, $old_instance) {
$instance = [];
$instance['legal_name'] = (!empty($new_instance['legal_name']))? strip_tags($new_instance['legal_name']): '';
$instance['vat_id'] = (!empty($new_instance['vat_id']))? strip_tags($new_instance['vat_id']): '';
$instance['street_address'] = (!empty($new_instance['street_address']))? strip_tags($new_instance['street_address']): '';
$instance['postal_code'] = (!empty($new_instance['postal_code']))? strip_tags($new_instance['postal_code']): '';
$instance['postal_city'] = (!empty($new_instance['postal_city']))? strip_tags($new_instance['postal_city']): '';
$instance['email_address'] = (!empty($new_instance['email_address']))? strip_tags($new_instance['email_address']): '';
$instance['phone_number'] = (!empty($new_instance['phone_number']))? strip_tags($new_instance['phone_number']): '';
return $instance;
}
Agora você pode testar seu widget, se quiser, e verificar se os valores inseridos estão sendo salvos. E se você se lembrar de definir o valueatributo corretamente em form(), ao salvar e clicar em atualizar, os valores devem ser mantidos. Excelente! Agora vamos para o último, e reconhecidamente mais divertido, passo – a saída do bit de front-end.
A função widget()
A widget()função é responsável pela saída do seu widget no frontend. Obteremos dois argumentos para a função; em primeiro lugar, um array com algumas informações úteis, como os wrappers de área de widget definidos pelo tema e, em segundo lugar, seus valores de configuração de widget salvos.
A saída do seu widget deve sempre começar com echoing $args['before_widget']e sempre terminar com echoing $args['after_widget']. Isso garante que seu widget seja encapsulado nos mesmos wrappers HTML de widget apropriados, conforme definido pelo tema. Ao longo das mesmas faixas, você pode ecoar $args['before_title']e $args['after_title']gerar wrappers HTML corretos em torno do título do widget. Não temos um título de widget real em si, mas agruparemos o nome legal da empresa como um título de widget.
Caso contrário, você obtém seus valores salvos referenciando o segundo argumento, $instance, por seus nomes de chave definidos em form()e update(). É uma boa prática produzir apenas as configurações que foram definidas – e ignorar as vazias.
Como também estamos gerando microdados, precisamos adicionar as propriedades correspondentes seguindo as regras do schema.org.
Você decide como deseja gerar o seu widget; você provavelmente pode considerar adicionar mais wrappers HTML para facilitar o estilo.
// Responsible for outputting the widget in frontend
public function widget($args, $instance) {
echo $args['before_widget'];
?><div itemscope itemtype="https://schema.org/LocalBusiness"><?php
if (!empty($instance['legal_name'])) {
echo $args['before_title'];
?><span itemprop="legalName"><?php echo $instance['legal_name']; ?></span><?php
echo $args['after_title'];
}
if (!empty($instance['vat_id'])) {
?><span itemprop="vatID" class="business-vatid"><?php printf(__('Vat: %s', 'txtdomain'), $instance['vat_id']); ?></span><?php
}
if (!empty($instance['street_address'])) {
?><div itemprop="address" itemscope itemtype="https://schema.org/PostalAddress" class="business-address"><?php
?><span itemprop="streetAddress"><?php echo $instance['street_address']; ?></span><?php
if (!empty($instance['postal_code'])) {
?><span itemprop="postalCode"><?php echo $instance['postal_code']; ?></span><?php
}
if (!empty($instance['postal_city'])) {
?><span itemprop="addressLocality"><?php echo $instance['postal_city']; ?></span><?php
}
?></div><?php
}
if (!empty($instance['email_address'])) {
?><a href="mailto:<?php echo $instance['email_address']; ?>" title="<?php _e('Send email', 'txtdomain'); ?>" class="business-email">
<span itemprop="email"><?php echo $instance['email_address']; ?></span>
</a><?php
}
if (!empty($instance['phone_number'])) {
?><a href="tel:<?php echo $instance['phone_number']; ?>" title="<?php _e('Call us', 'txtdomain'); ?>" class="business-phone">
<span itemprop="telephone"><?php echo $instance['phone_number']; ?></span>
</a><?php
}
?></div><?php
echo $args['after_widget'];
}
Personalize a saída, adicione algum estilo e pronto!
FYI: Seu widget receberá o nome da classe de encapsulamento ” widget_<base ID>" (ID base é o que você forneceu no construtor). No nosso caso, nosso widget receberá a classe ” widget_local_business“. Isso pode ajudá-lo a adicionar algum estilo direcionado.
Encerrando e código final
Neste tutorial, aprendemos como criar um widget personalizado e como renderizar uma saída formatada de microdados a partir de suas configurações. Você deve ser capaz de criar seus próprios widgets, seguindo o básico de uma classe de widgets!
Para referência, aqui está o código completo, tudo junto.
add_action('widgets_init', function() {
register_widget('LocalBusiness');
});
class LocalBusiness extends WP_Widget {
// Initialize your widget in the class constructor
public function __construct() {
$widget_ops = [
'description' => __('Outputs business information with Microdata', 'txtdomain')
];
parent::__construct('local_business', __('Local Business Information', 'txtdomain'), $widget_ops);
}
// Responsible for outputting the widget in frontend
public function widget($args, $instance) {
echo $args['before_widget'];
?><div itemscope itemtype="https://schema.org/LocalBusiness"><?php
if (!empty($instance['legal_name'])) {
echo $args['before_title'];
?><span itemprop="legalName"><?php echo $instance['legal_name']; ?></span><?php
echo $args['after_title'];
}
if (!empty($instance['vat_id'])) {
?><span itemprop="vatID" class="business-vatid"><?php printf(__('Vat: %s', 'txtdomain'), $instance['vat_id']); ?></span><?php
}
if (!empty($instance['street_address'])) {
?><div itemprop="address" itemscope itemtype="https://schema.org/PostalAddress" class="business-address"><?php
?><span itemprop="streetAddress"><?php echo $instance['street_address']; ?></span><?php
if (!empty($instance['postal_code'])) {
?><span itemprop="postalCode"><?php echo $instance['postal_code']; ?></span><?php
}
if (!empty($instance['postal_city'])) {
?><span itemprop="addressLocality"><?php echo $instance['postal_city']; ?></span><?php
}
?></div><?php
}
if (!empty($instance['email_address'])) {
?><a href="mailto:<?php echo $instance['email_address']; ?>" title="<?php _e('Send email', 'txtdomain'); ?>" class="business-email">
<span itemprop="email"><?php echo $instance['email_address']; ?></span>
</a><?php
}
if (!empty($instance['phone_number'])) {
?><a href="tel:<?php echo $instance['phone_number']; ?>" title="<?php _e('Call us', 'txtdomain'); ?>" class="business-phone">
<span itemprop="telephone"><?php echo $instance['phone_number']; ?></span>
</a><?php
}
?></div><?php
echo $args['after_widget'];
}
// Responsible for outputting the widget settings in admin
public function form($instance) {
?>
<p>
<label for="<?php echo $this->get_field_id('legal_name'); ?>"><?php _e('Legal name:', 'txtdomain'); ?></label>
<input type="text" class="widefat" id="<?php echo esc_attr($this->get_field_id('legal_name')); ?>" name="<?php echo esc_attr($this->get_field_name('legal_name')); ?>" value="<?php echo esc_attr($instance['legal_name']); ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id('vat_id'); ?>"><?php _e('Vat ID/Organization number:', 'txtdomain'); ?></label>
<input type="text" class="widefat" id="<?php echo esc_attr($this->get_field_id('vat_id')); ?>" name="<?php echo esc_attr($this->get_field_name('vat_id')); ?>" value="<?php echo esc_attr($instance['vat_id']); ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id('street_address'); ?>"><?php _e('Street address:', 'txtdomain'); ?></label>
<input type="text" class="widefat" id="<?php echo esc_attr($this->get_field_id('street_address')); ?>" name="<?php echo esc_attr($this->get_field_name('street_address')); ?>" value="<?php echo esc_attr($instance['street_address']); ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id('postal_code'); ?>"><?php _e('Postal code:', 'txtdomain'); ?></label>
<input type="text" class="widefat" id="<?php echo esc_attr($this->get_field_id('postal_code')); ?>" name="<?php echo esc_attr($this->get_field_name('postal_code')); ?>" value="<?php echo esc_attr($instance['postal_code']); ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id('postal_city'); ?>"><?php _e('City:', 'txtdomain'); ?></label>
<input type="text" class="widefat" id="<?php echo esc_attr($this->get_field_id('postal_city')); ?>" name="<?php echo esc_attr($this->get_field_name('postal_city')); ?>" value="<?php echo esc_attr($instance['postal_city']); ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id('email_address'); ?>"><?php _e('E-mail address:', 'txtdomain'); ?></label>
<input type="text" class="widefat" id="<?php echo esc_attr($this->get_field_id('email_address')); ?>" name="<?php echo esc_attr($this->get_field_name('email_address')); ?>" value="<?php echo esc_attr($instance['email_address']); ?>" />
</p>
<p>
<label for="<?php echo $this->get_field_id('phone_number'); ?>"><?php _e('Phone number:', 'txtdomain'); ?></label>
<input type="text" class="widefat" id="<?php echo esc_attr($this->get_field_id('phone_number')); ?>" name="<?php echo esc_attr($this->get_field_name('phone_number')); ?>" value="<?php echo esc_attr($instance['phone_number']); ?>" />
</p>
<?php
}
// Responsible for saving settings in admin
public function update($new_instance, $old_instance) {
$instance = [];
$instance['legal_name'] = (!empty($new_instance['legal_name']))? strip_tags($new_instance['legal_name']): '';
$instance['vat_id'] = (!empty($new_instance['vat_id']))? strip_tags($new_instance['vat_id']): '';
$instance['street_address'] = (!empty($new_instance['street_address']))? strip_tags($new_instance['street_address']): '';
$instance['postal_code'] = (!empty($new_instance['postal_code']))? strip_tags($new_instance['postal_code']): '';
$instance['postal_city'] = (!empty($new_instance['postal_city']))? strip_tags($new_instance['postal_city']): '';
$instance['email_address'] = (!empty($new_instance['email_address']))? strip_tags($new_instance['email_address']): '';
$instance['phone_number'] = (!empty($new_instance['phone_number']))? strip_tags($new_instance['phone_number']): '';
return $instance;
}
}
