Aprenda a restringir o login de editores no WordPress por horário.

Você já precisou limitar o horário de acesso de alguns usuários em seu site WordPress?

Neste tutorial, vou te ensinar como restringir o login de editores (ou qualquer outro papel/role que você desejar) no WordPress para um determinado horário, garantindo mais segurança e controle sobre quem acessa seu site em horários específicos.


Essa função em WordPress verifica se o usuário que está tentando fazer login é um editor e se o horário atual está entre 9h e 14h, de segunda a sexta-feira. Se essas condições forem atendidas, o editor é automaticamente desconectado, redirecionado para a página inicial e o processo de login é encerrado. Você pode refinar essa funcionalidade e redirecionar para uma página contendo um aviso ou outro conteúdo.

No arquivo functions.php insira a função abaixo:

/**
 * Verifica se o papel do usuário está na lista de papéis restritos e se o horário atual está entre 9h e 14h, de segunda a sexta-feira.
 *
 * @return void
 */

function restringir_login_editor() {
    $usuario_atual = wp_get_current_user();

    if (in_array('editor', (array) $usuario_atual->roles)) {
        $horario_atual = current_time('H:i');
        $dia_semana = date('N');  // Obtém o número do dia da semana (1 para segunda, 2 para terça, etc.)

        // Se o horário estiver entre 9h e 14h e for um dia útil (segunda a sexta-feira)
        if ($horario_atual >= '09:00' && $horario_atual <= '14:00' && $dia_semana >= 1 && $dia_semana <= 5) {
            // Desloga o editor, redireciona para a página inicial e encerra o processo de login
            wp_logout();
            wp_redirect(home_url());
            exit;
        }
    }
}

// Adiciona a ação para verificar o horário e dia da semana no momento do login
add_action('wp_login', 'restringir_login_editor');

Com este simples tutorial, você aprendeu como restringir o login de editores no WordPress com base no horário atual. Essa funcionalidade pode ser útil para garantir que determinados usuários acessem o site apenas durante o horário desejado, aumentando a segurança e o controle sobre o acesso ao seu site WordPress.

Se preferir não usar código, existe um plugin que realiza a mesma ação:

Simplificando a Criação de Conteúdo com “wp post generate”

Você já se perguntou como agilizar a criação de posts no WordPress? A resposta pode estar no comando wp post generate. Vamos explorar como usar essa ferramenta e como ela pode ser benéfica para otimizar a produção de conteúdo.

O que é wp post generate?

O WP-CLI, uma interface de linha de comando para o WordPress, oferece uma funcionalidade poderosa chamada wp post generate. Com esse comando, podemos criar posts facilmente, e isso é especialmente útil quando precisamos gerar conteúdo fictício para testes ou para preencher um site com dados de exemplo.

Como Usar o Comando

A sintaxe básica é simples:

wp post generate --count=5 --post_type=post

Este comando cria 5 posts do tipo ‘post’ com títulos, conteúdo e metadados aleatórios.

Benefícios para Produtores de Conteúdo

  1. Eficiência na Criação: Imagine a facilidade de gerar múltiplos posts com um simples comando. Isso economiza tempo, especialmente ao criar ambientes de teste ou ao preencher um site com conteúdo de exemplo.
  2. Testes e Desenvolvimento: Desenvolvedores podem utilizar wp post generate para criar rapidamente uma variedade de posts e testar o design, layout e funcionalidades do site em diferentes cenários.
  3. Treinamento e Demonstração: Ao criar posts fictícios, é possível realizar treinamentos ou demonstrações sem comprometer o conteúdo real do site.

Dicas Adicionais:

  • Personalização Avançada: O comando wp post generate suporta várias opções para personalizar o conteúdo gerado, como definir o autor, a data de publicação e outros metadados.
  • Adapte para Suas Necessidades: Ajuste os parâmetros conforme necessário, escolhendo o tipo de post, status e outras opções que se alinhem com seus requisitos.

Em resumo, wp post generate é uma ferramenta valiosa para simplificar a criação de posts no WordPress, oferecendo eficiência e flexibilidade. Experimente e descubra como ela pode beneficiar seu fluxo de trabalho de produção de conteúdo.

Passando variáveis do PHP para javascript através do head [WordPress]

Utilizar dados fornecidos através de funções ou variáveis de PHP em algum código javascript já foi ou será uma necessidade em algum momento para quem trabalha com WordPress. existe uma função específica para trazer variáveis do backend para o front: wp_localize_script().

Vamos tomar como exemplo um código JavaScript que irá receber o ID do post. (E sim! Existem outros meios de identificar o ID do post utilizando o JavaScript, é apenas um exemplo 😊)

Começaremos pelo código PHP. Crie uma função na qual o arquivo JavaScript é registrado antes da função wp_localize_script(), caso contrário não irá funcionar.

PHP

function passar_variaveis() {
	global $post;
	wp_enqueue_script('variaveis-post-id', 'assets/src/js/global.js');
	wp_localize_script('variaveis-post-id', 'post_id', $post->ID);
 
}
add_action('wp_enqueue_scripts', 'passar_variaveis');

Também é possível passar várias variáveis ao mesmo tempo:

function passar_variaveis() {
	global $post;
         $todas_variaveis = array(
             'post_id'       => $post->ID,
              'variavel_1'   => 'var_1',
              'variavel_2'. => 'var_2'
         );
	wp_enqueue_script('variaveis-post-id', 'assets/src/js/global.js');
	wp_localize_script('variaveis-post-id', 'post_id', $post->ID);
 
}
add_action('wp_enqueue_scripts', 'passar_variaveis');

Javascript

Apenas uma variável:

var post_id = window.post_id;

Diversas variáveis:

var post_id = window.post_id;
var variavel_1 = window.variavel_1;
var variavel_2 = window.variavel_2;

Resultado – HTML

Analisando o HTML renderizado é possível ver a variável disponível dentro do <head> e pronto para ser usado pelo javascript:

<script id="variaveis-post-id">
    var post_id = 10;
</script>

Foto de Alex Andrews: https://www.pexels.com/pt-br/foto/tres-brinquedos-de-monofone-pretos-821754/

Crie um ambiente local usando WordPress VIP e Docker

Recentemente tive experiências ruins na hora de configurar ambientes locais de WordPress VIP usando Chassis. Percebendo o tempo que vinha gastando eu decidi utilizar uma ferramenta com a qual tenho mais familiaridade: Docker.

A troca valeu a pena! Estou rodando diversos ambientes – a maioria multisite – e minha máquina vem aguentando bem, sem travar e com o banco de dados rodando com velocidade. 😎

Antes de iniciar o passo-a-passo devo dizer que existe uma documentação oficial sobre o assunto. Mas eu gostaria de esmiuçar mais o assunto e trazê-lo para o português.

Requerimentos ⚠

  1. npm
  2. nvm
  3. Docker Desktop

Passo a passo 👣

  1. Primeiramente, ajuste a versão do Node para 14 ou superior: nvm use 14
  2. Instale o VIP: npm install -g @automattic/vip
  3. Certifique-se que o Docker está aberto e rodando.
  4. Crie um novo ambiente de desenvolvimento: vip dev-env create --slug=site-exemploNão se preocupe com pastas e repositórios nesse momento.
  5. Configure o novo ambiente (dev-env) seguindo os passos:
    ✔ WordPress site title · Site Exemplo
    ✔ Multisite (y/N) · true
    ✔ PHP version to use · 8.0
    ✔ WordPress – Which version would you like · 6.1
    ✔ How would you like to source vip-go-mu-plugins · image
    ✔ How would you like to source application code · local
    ✔ What is a path to your local application code · ./site-exemplo

    ➡️ Nesse último passo eu apontei o ambiente para uma pasta clonada de um repositório chamado site-exemplo. Caso escolha seu próprio repositório certifique-se que esta contém as pastas: plugins, themes, private, images, client-mu-plugins, vip-config. Mas você pode escolher utilizar uma cópia do repositório VIP, escolha a opção local.
    ✔ Enable Elasticsearch (needed by Enterprise Search)? (y/N) · true
    ✔ Enable phpMyAdmin (y/N) · false
    ✔ Enable XDebug (y/N) · true
    ✔ Enable MailHog (y/N) · false
  6. Agora o VIP lhe dará as urls e informação sobre o ambiente criado:
    SLUG site-exemplo
    LOCATION /Users/.local/share/vip/dev-environment/site-exemplo
    SERVICES devtools, nginx, php, database, memcached, wordpress, vip-mu-plugins
    NGINX URLS http://site-exemplo.vipdev.lndo.site/
    STATUS DOWN
    DEFAULT USERNAME vipgo
    DEFAULT PASSWORD password
  7. Pronto! Ambiente criado!
  8. Inicie o novo ambiente: vip dev-env start --slug=site-exemplo – Isso pode demorar um pouco na primeira vez.
  9. Se algo der errado rode o comando:
    vip dev-env start --slug=site-exemplo --debug @automattic/vip:bin:dev-environment
  10. Agora você pode acessar a URL:  http://site-exemplo.vipdev.lndo.site/wp-admin/
  11. Se você tem alguma cópia de algum banco de dados é hora de importá-lo e rodar o comando search-replace, deixe o arquivo sql na raiz:
    vip dev-env import sql database.sql --slug=site-exemplo --search-replace="url-antiga-aqui,site-exemplo.vipdev.lndo.site"
  12. Limpe o cache: vip dev-env exec --slug example-site -- wp cache flush
  13. Crei um novo usuário e senha, se desejar: vip dev-env exec –slug=site-exemplo — wp user create USERNAME-AQUI EMAIL-DO-USUÁRIO —user_pass=password –role=administrator
  14. Se desejar, adicione o novo usuário como super admin: vip dev-env exec --slug=site-exemplo -- wp super-admin add USERNAME-AQUI

É isso! Agora é sua vez de tentar! Em caso de dúvidas é só deixar nos comentários.

Como limitar caracteres e manter palavras inteiras em strings no PHP.

Certamente você já se deparou com a dificuldade em limitar a quantidade de caracteres e não cortar palavras em títulos e resumos.

Função limitadora

Apresento uma função que quando aplicada é capaz de limitar a quantidade de caracteres e manter as palvras intactas. Seguem dois exemplos:

Frase original:

Hoje está um belo dia de sol e vamos comemorar meu aniversário.

Frase com caracteres limitados SEM uso da função:

Hoje está um belo dia de sol e vamos comem

Frase com caracteres limitados COM uso da função:

Hoje está um belo dia de sol e vamos…

Construindo a função

<?php

function trim_title_keep_words($title, $max_lenght, $more)  {
    // Title will remain untouched if character counut is smaller than max lenght
    // O título permanecerá intacto se a quantidade de caracteres for menor que o máximo estabeleido.
    if (strlen($title) <= $max_lenght) {
        return $title;
    }
    
    // Title is trimmed and word are kept intact
    // O título é cortado mas a última palavra permanece inteira                               
    $trimmed_title = substr($title, 0, $max_lenght);
    if ( substr($trimmed_title,-1,1) != ' ' ) {
        $trimmed_title = substr($trimmed_title, 0, strrpos($trimmed_title, " "));
    }
    // Adding read more to final                              
    $trimmed_title = $trimmed_title.$more;
    return $trimmed_title;
}                

Como usar essa função

  1. Identifique os parâmetros que serão usados na função: trim_title_keep_words($title, $max_lenght, $more)

    $title -> use a função do WordPress para pegar o título

    $max_lenght -> defina quantos characteres devem ter no máximo

    $more -> Defina que símbolo quer usar para indicar que o título foi cortado. Exemplo.: …, >>, +

  2. Aplique a função e imprima o resultado: 
    $new_title = trim_title_keep_words( get_the_title(), 30, ‘…’);
    echo $new_title;

Resultado esperado:

Título cortado SEM essa função: “Olá meu mundo li…”

Título cortado COM essa função: “Olá meu mundo…”

Você pode encontrar esse código meu GitHub

WordCamp São Paulo 2021: Palestra Elementor

 

Como usar Controles de Conditions no Elementor

Garanta uma boa experiência e um código mais limpo

Widgets customizados possuem a vantagem de serem extremamente versáteis e gerantem um conteúdo diversificado (texto, imagem, vídeo) com apenas um Widget.

O uso desses controles pode deixar seu código mais limpo e garantir uma experiência melhor ao utilizar o Widget em uma página.

Para ilustrar esse exemplo vamos utilizar um widget bem simples que conta com os seguintes itens:

  • Titulo
  • Texto
  • Imagem ou Vídeo (nunca ambos)

Esse é o visual do Widget:

O vídeo e a imagem abaixo ilustram um exemplo de Controle Condicional  aplicado a um Widget do Elementor.

Ao aplicar o Controle de Condicional é dado ao usuário o poder de escolher qual tipo de mídia será usado, não havendo a necessidade de mostrar ambos os campos (vídeo ou imagem), sendo que apenas um será usado. E o no código surge a possibilidade de renderizar o conteúdo escolhido pelo usuário. 

Mas como utilizar uma condition?

Primeiro, entenda o que é um control

Ao criar um novo Widget para o Elementor (aprenda como fazer isso aqui) você deve registrar controls para isso. 

Exemplo de um control que usamos em nosso widget, o Título (TEXT)

$this->add_control(
		'titulo',
		[
			'label' => __( 'Título', 'plugin-domain' ),
			'type' => Controls_Manager::TEXT,
			'placeholder' => __( 'Insira o título aqui', 'pipefy-2020-admin' ),
		]
    ); 

E isso resultará em:

Note que utilizamos vários parâmetros dentro do control: label, type e placeholder. Para usarmos o parâmetro de condition basta inseri-lo dentro do de um control.

Já sabe o que é um control? Vamos seguir!

Passo a passo

Agora que você já está familiar ao conceito de control podemos começar a inseir o parâmetro de condition em um exemplo real.

Passo 1

Primeiro vamos criar um control de CHOOSE (veja mais sobre aqui), para que o usuário possa escolher entre imagem ou vídeo.

$this->add_control(
			'imagem_ou_video',
			[
				'label' => __( 'Usar imagem ou vídeo?', 'plugin-domain' ),
				'type' => \Elementor\Controls_Manager::CHOOSE,
				'options' => [
					'imagem' => [
						'title' => __( 'Imagem', 'plugin-domain' ),
						'icon' => 'fa fa-image',
					],
					'video' => [
						'title' => __( 'Vídeo', 'plugin-domain' ),
						'icon' => 'fa fa-video',
					],
				],
				'default' => 'imagem',
				'toggle' => true,
			]
		); 

Passo 2

Vamos criar o um control para a imagem e já inserir uma condition (condição) para que ela apareça para o usuário. E a condição é que o control ‘imagem_ou_vídeo’ seja igual a opção ‘imagem’.

$this->add_control(
		'selecionar_image',
		[
			'label'   => __( 'Imagem', 'plugin-domain' ),
			'type'    => \Elementor\Controls_Manager::MEDIA,
			'default' =>
			  [
				'url'  => \Elementor\Utils::get_placeholder_image_src(),
			  ],
			  'condition' => 
			  [
			    'imagem_ou_video' => 'imagem',
			  ],
		]
	); 

Passo 3

Agora vamos criar o um control para o vídeo e também inserir uma condition (condição) para que ela apareça para o usuário. Dessa vez a condição é que o control ‘imagem_ou_vídeo’ seja igual a opção ‘video’.

$this->add_control(
		'selecionar_image',
		[
			'label'   => __( 'Imagem', 'plugin-domain' ),
			'type'    => \Elementor\Controls_Manager::MEDIA,
			'default' =>
			  [
				'url'  => \Elementor\Utils::get_placeholder_image_src(),
			  ],
			  'condition' => 
			  [
			    'imagem_ou_video' => 'imagem',
			  ],
		]
	); 

 Pronto!

Ao selecionar o ícone “Imagem”, logo abaixo o campo de imagem aparecerá para que o usuário insira a imagem de sua preferência. E ao selecionar o ícone “Vídeo” é possível inserir o vídeo desejado.

🎉 Bônus!

Você pode utilizar o parâmetro de condition de modo mais avançado. Nesse modo utilizaremos no plural condiitons. 

Relação AND/OR:

  'conditions' => 
  [
    'relation' => 'and', //podemos usar 'and' ou 'or'
    'terms' => 
    [
        [
            'name' => 'imagem_ou_video',
            'operator' => '==',
            'value' => 'imagem'
        ],
        [
            //vamos imaginar que criamos um control SWITCHER para mostrar ou não o título, chamado 'mostrar_titulo'
            'name' => 'mostrar_titulo',
            'operator' => '==', //aqui podemos utilizar outros operadores do php ex: >= , !==, < . etc
            'value' => 'sim'
        ]
    ]
  ] 

Post photo by Justin Luebke on Unsplash

Crie Widgets personalizados no Elementor

Saiba como criar Widgets personalizados no Elementor.

Por que criar plugins personalizados?

  • Maior controle sobre o seu código
  • Evita a necessidade de instalar novos plugins
  • Atender sua demanda com apenas um Widget

Passo a passo

1- Instale o Elementor

Caso não tenha o plugin do Elementor instalado você pode fazê-lo diretamente na sessão de plugins do WordPress. Ou se preferir faça o download aqui.

 

2- Crie um arquivo de listagem de widgets

Na pasta do seu tema (preferencialmente no tema filho) crie os seguintes arquivos:

  1. listagem-widgets.php
  2. Crie uma pasta chamada “widgets”
  3. Dentro da pasta widgets crie um arquivo chamado meu-primeiro-widget.php
  4. Adiocione no arquivo function.php a linha:
    require_once ‘listagem-widgets.php’;

Estrutura:

  • Tema do WordPress
  • Tema filho
    • listagem-widgets.php
      • file_folder  widgets
      • meu-primeiro-widget.php

Estrutura do arquivo de listagem (listagem-widgets.php):

Após criar um namespace (que chamei de Meus_Widgets você deverá adicionar basicamente duas funções:

  • include_widget_files() – para anexar o arquivo do widget
  • register_widgets() – para registrar os widgets na listagem do Elementor
<?php
namespace Meus_Widgets;

// use Elementor\Plugin;
class Widget_Loader {

	private static $_instance = null;

	public static function instance() {
		if ( is_null( self::$_instance ) ) {
			self::$_instance = new self();
		}
		return self::$_instance;
	}


	private function include_widgets_files() {
		require_once __DIR__ . '/widgets/meu-primeiro-widget.php';
	}

	public function register_widgets() {

		$this->include_widgets_files();

		\Elementor\Plugin::instance()->widgets_manager->register_widget_type( new Widgets\Meu_Primeiro_Widget() );

	}

	public function __construct() {
		add_action( 'elementor/widgets/widgets_registered', array( $this, 'register_widgets' ), 99 );
	}

}

// Instantiate Plugin Class
Widget_Loader::instance();
 

3- Começando a trabalhar no widget

Criar um widget para o Elementor não é muito diferente de criar um widget para o WordPress. Basta criar uma classe que faça a extensão do Widget_Base e preencher os métodor necessários.

Cada widget prescisa de alguns itens básicos tais como:

  1. Nome único que será identificado pelo nome
  2. Título para o catálogo do Elementor
  3. Ìcone para o catálogo do Elementor
<?php 
class Meu_Primeiro_Widget extends \Elementor\Widget_Base {
    public function get_name(){}
    public function get_title() {}
    public function get_icon() {}
    public function get_categories() {}
    protected function _register_controls() {}
    protected function render() {}
    protected function _content_template() {}
} 

Detalhando:

  • Nome do widget – O método get_name()  é simples, você só precisa retornar o nome do widget que será usado no código.
  • Título do widget – O método get_title (), que, novamente, é muito simples, você precisa retornar o título do widget que será exibido como o rótulo do widget.
  • Ícone do widget – o método get_icon () é um método opcional, mas recomendado, pois permite definir o ícone do widget. você pode usar qualquer um dos ícones eicon ou font-awesome, basta retornar o nome da classe como uma string.
  • Categorias de widget – o método get_categories permite definir a categoria do widget e retornar o nome da categoria como uma string.
  • Controles de widget – O método _register_controls permite definir quais controles (campos de configuração) seu widget terá.
  • Render Frontend Output – O método render (), que é onde você realmente renderiza o código e gera o HTML final no frontend usando PHP.
  • Render Editor Output – O método _content_template (), é onde você renderiza a saída do editor para gerar a visualização ao vivo usando um modelo Backbone JavaScript.

Vamos começar a juntar as peças:

Para colocar todas as peças juntas, vamos criar um widget Elementor simples que usará a funcionalidade nativa oEmbed do WordPress.

Widget Class

Primeiro crie a classe que estenda a Widget_Base class:

class Meu_Primeiro_Widget extends \Elementor\Widget_Base {
} 

Widget Data

Agora vamos começar a preencher os métodos:

<?php
class Elementor_Test_Widget extends \Elementor\Widget_Base {

	public function get_name() {
		return 'meu-primeiro-widget';
	}

	public function get_title() {
		return 'Meu primeiro widget';
	}

	public function get_icon() {
		return 'fa fa-trophy';
	}

	public function get_categories() {
		return [ 'meus widgets' ];
	}

} 

Widget Controls

Em seguida, precisamos adicionar os controles do widget usando o método _register_controls (). Optei por utilizar o controle de texto.
Aqui você pode visualizar todos os controls do Elementor e suas aplicações.

<?php
class Elementor_Test_Widget extends \Elementor\Widget_Base {


protected function _register_controls() {

		$this->start_controls_section(
			'secao_conteudo',
			[
				'label' => 'Conteúdo',
				'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
			]
		);

		$this->add_control(
			'titulo',
			[
				'label' => __( 'titulo', 'plugin-domain' ),
				'type' => \Elementor\Controls_Manager::TEXT,
				'default' => 'Título padrão',
				'placeholder' => 'Insira o título aqui',
			]
		);

		$this->end_controls_section();

	}


} 

Visualização no Frontend

E, por último, precisamos implementar nosso método render() que obtém o text que o usuário insere no controle de TEXT acima e obtém o conteúdo.

<?php 
class Meu_Primeiro_Widget extends \Elementor\Widget_Base {
    //PHP Render
    protected function render() {
        $settings = $this->get_settings_for_display();
        ?>
        <div><?php echo $settings['titulo']; ?></div>;
    }
} 

Bônus: Visualização em tempo real no Elementor

Adicionando a função_content_template() é possível observar as alterações em tempo real no editor, permitindo recriar o método render () em JavaScript.

<?php
    //JS RENDER
    protected function _content_template() {
    ?>
		<div>{{{ settings.titulo }}}</div>
	<?php
	} 

O widget está pronto! Você pode adicionar diversos controles no mesmo widget e obter algo mais complexo, veja aqui a lista. Ou Consulte meu GitHub para widgets com maior variedade.

Código completo

<?php

namespace Meus_Widgets;

use Elementor\Widget_Base;
use Elementor\Controls_Manager;

if (!defined('ABSPATH')) exit; // Exit if accessed directly


class Meu_Primeiro_Widget extends Widget_Base{

  public function get_name(){
    return 'meu-primeiro-widget';
  }

  public function get_title(){
    return 'Meu primeiro widget';
  }

  public function get_icon(){
    return 'fa fa-trophy';
  }

  public function get_categories(){
    return ['meus widgets'];
  }

  protected function _register_controls(){
    $this->start_controls_section(
			'secao_conteudo',
			[
				'label' => 'Conteúdo',
				'tab' => \Elementor\Controls_Manager::TAB_CONTENT,
			]
		);

		$this->add_control(
			'titulo',
			[
				'label' => __( 'titulo', 'plugin-domain' ),
				'type' => \Elementor\Controls_Manager::TEXT,
				'default' => 'Título padrão',
				'placeholder' => 'Insira o título aqui',
			]
		);

		$this->end_controls_section();
  }

  //PHP Render
  protected function render() {
		$settings = $this->get_settings_for_display();
  ?>
    <div><?php echo $settings['titulo']; ?></div>
  <?php
  }
  
  //JS RENDER
  protected function _content_template() {
		?>
		<div>{{{ settings.titulo }}}</div>
		<?php
	}
}