Menu

Adicionando Menu de Navegação Wordpress - Tema customizado

O Wordpress nos permite criar menus personalizados para serem exibidos no tema, de forma dinâmica. No entanto, é necessário informar ao Wordpress que seu tema tem suporte a eles, assim, conseguimos configurar diretamente pelo menu aparência.

Para informar ao wordpress que o tema dá suporte a menus, precisamos criar o arquivo functions.php na raiz do nosso tema. (Se o arquivo já existir não é necessários criar outro).

Sempre que precisamos informar algo específico par ao wordpress, é através desse arquivo de configurações específico. Nele são utilizadas as Actions Hooks do wordpress.

Cada ação que pode ser especificada, possuí uma Action específica que pode ser consultada neste link.

Para especificar uma ação, criaremos uma função que adiciona o menu que desejamos, e ao inicializar o wordpress, incluiremos a função que criamos para que o menu customizado seja exibido.

Para exemplificar, a função:

function meu_tema_personalizado_registrando_menu(){
    register_nav_menu(
        'menu-navegacao', //id para o menu poder ser referenciado no tema
        'Menu Navegação' //nome para exibição
    ); 
}

//informando ao wordpress qual momento executar nossa função personalizada
add_action('init', 'meu_tema_personalizado_registrando_menu');

Para especificar o local onde o menu deve aparecer, colocamos este código no header.php (para mais informações consulte documentação oficial)

wp_nav_menu(
        array(
                'menu' => 'menu-navegacao'
        )
);
wp_nav_menu( array $args = array(
	'menu'				=> "", // (int|string|WP_Term) Desired menu. Accepts a menu ID, slug, name, or object.
	'menu_class'		=> "", // (string) CSS class to use for the ul element which forms the menu. Default 'menu'.
	'menu_id'			=> "", // (string) The ID that is applied to the ul element which forms the menu. Default is the menu slug, incremented.
	'container'			=> "", // (string) Whether to wrap the ul, and what to wrap it with. Default 'div'.
	'container_class'	=> "", // (string) Class that is applied to the container. Default 'menu-{menu slug}-container'.
	'container_id'		=> "", // (string) The ID that is applied to the container.
	'fallback_cb'		=> "", // (callable|bool) If the menu doesn't exists, a callback function will fire. Default is 'wp_page_menu'. Set to false for no fallback.
	'before'			=> "", // (string) Text before the link markup.
	'after'				=> "", // (string) Text after the link markup.
	'link_before'		=> "", // (string) Text before the link text.
	'link_after'		=> "", // (string) Text after the link text.
	'echo'				=> "", // (bool) Whether to echo the menu or return it. Default true.
	'depth'				=> "", // (int) How many levels of the hierarchy are to be included. 0 means all. Default 0.
	'walker'			=> "", // (object) Instance of a custom walker class.
	'theme_location'	=> "", // (string) Theme location to be used. Must be registered with register_nav_menu() in order to be selectable by the user.
	'items_wrap'		=> "", // (string) How the list items should be wrapped. Default is a ul with an id and class. Uses printf() format with numbered placeholders.
	'item_spacing'		=> "", // (string) Whether to preserve whitespace within the menu's HTML. Accepts 'preserve' or 'discard'. Default 'preserve'.
) );

Criando um tema customizado no Wordpress

Obs: O blogger não permite colocar tags php nos blocos de código. Então toda vez que mencionar entre chaves php me refiro a esse tipo de código:

 

Configuração Básica

Já tendo o wordpress instalado e configurado na sua máquina, para criar um tema novo é bem simples.

Primeiro passo é criar uma pasta para seu novo tema dentro de:

 C:\xampp\htdocs\wordpress\wp-content\themes 

Dentro da sua nova pasta crie um arquivo style.css e outro com nome de index.php.

Essa é a estrutura básica para um tema ser reconhecido.


Se entrar no painel do wordpress será possível visualizar o tema, porém não haverá nenhuma informação relevante como nos outros temas.

Para incluir essas informações sobre tema, é preciso incluir como forma de comentários dentro do arquivo style.css

/*
Theme Name: Aprendendo Wordpress 
Author: Seu nome
Description: Tema customizado criado para aprendizagem do wordpress.
Version: 1.0.0
Tags: aprendizado, customizacao, 
*/

Para que o thumbnail com o preview do tema apareça também é necessário ter essa imagem, nomear screenshot.jpg e incluir na pasta principal.


Para configurar o tema:

É possível incluir todo o site/blog num único arquivo index.php? Sim, funcionaria. Mas não é o objetivo de se criar um tema do Wordpress, pois não refletiria as alterações feitas dentro da plataforma do Wordpress, mas vamos por partes

Criando o Cabeçalho para o tema

Para criar o cabeçalho crie um arquivo chamado header.php.

No arquivo header.php teremos toda estrutura inicial da nossa página html. Literalmente o mas com algumas alterações.

Crie um página html normalmente, porém deixe o código até a abertura da tag body. No lugar do título, entre código PHP, coloque o código wordpress correspondente:

bloginfo('name');  

Logo após o título, também é necessário incluir um código para que todo o layout funciona (inclua este código entre chaves php):

 wp_head(); 

Criando o Rodapé para o tema

Para criar o rodapé crie um arquivo chamado footer.php.

Neste arquivo feche a tag body aberta do cabeçalho e incluia o seguinte código entre chaves php:

wp_footer();

Não se esqueça de fechar a tag html também aberta do cabeçalho. Ao final todos os arquivos irão de unir e formar um arquivo só, por isso temos que abrir e fechar todas as tags.


Se você já tiver uma página em html criada, pode copiar e colar o conteúdo do cabeçalho e do rodapé nos arquivos que criamos para eles.

Configurando o arquivo index.php

Agora que já configurei o cabeçalho e o rodapé, posso chamar esses arquivos no arquivo principal criado: o index.php

Para incluir o arquivo do cabeçalho dentro do index.php, use o seguinte código entre chaves php:

require_once 'header.php';

E para incluir o rodapé, temos um código semelhante:

require_once 'footer.php';

Conhecendo Arrays em C#

O array é um tipo de referência, não é um tipo de valor!

Quando tenho variáveis que compartilham o mesmo contexto, posso "juntar" todas num tipo chamado array! Um array agrupará vários tipos da mesma variável sendo possível consultar por índices. Por exemplo: 

Tenho um conjunto de peças, e quero guardar quantas peças iguais tenho em cada conjunto. Supondo que seria uma coleção de números inteiros: 

int conjunto_1 = 15;
int conjunto_2 = 20;
int conjunto_3 = 13;
int conjunto_4 = 22;

Para representar todos os conjuntos agrupados, sem ter que declarar uma variavel para cada um, podemos usar um conjunto de números interios, representado por um array, dessa forma:

int[] conjunto;

Para inicializar essa nova variavel que declaramos, que é do tipo array, precisamos informar ao compilador que estamos criando uma váriável que suporta diversos valores do tipo inteiro. Não basta simplesmente atribuir um valor inteiro, pois não é mais um valor inteior único... é um conjunto de valores inteiros.

O compilador também precisa saber quantos valores iremos armarezar na memória, qual a quantidade de espaço ele precisará cirar, e para isso, informamos também esse valor!

int[] conjunto = new int[4];
conjunto[0] = 15;
conjunto[1] = 20;
conjunto[2] = 13;
conjunto[3] = 22;

Dessa forma, criamos um array de inteiros com 4 posições (lembrando que o índice inicial aqui sempre será zero). Mas o que acontece se você inicilizar um array de 4 posições e não colocar nenhum valor nessa última posição? O valor padrão de inicialização é 0! Agora, como iterar sobre esse array? Fácil! Podemos acessar algumas propriedade especificas do array:
for(int indice = 0; indice < conjunto.Length; indice++){
	Console.WriteLine($"Acessando o array no índice: {indice}, com valor: conjunto[{indice}]");
}

Entendendo Herança e Interface em C#

Começando pela Herança:
Herança é um princípio de orientação a objetos, que permite que classes compartilhem atributos e métodos, através de "heranças". Ela é usada na intenção de reaproveitar código ou comportamento generalizado ou especializar operações ou atributos
Dessa forma, podemos criar uma situação hipotética para exemplificar uma herança. Supondo que temos um sistema de uma empresa. Nesta empresa teremos funcionários... então vamos criar a classe funcionario:
public class Funcionario
{
	public string Nome { get; set; }
	public string CPF { get; set; }
	public double Salario { get; set; }
}
Mas os funcionários podem ter características específicas, tais como Diretor, Desenvolvedor, Vendedor, etc... Normalmente, poderíamos criar para cada um outra classe:
public class Diretor
{
	public string Nome { get; set; }
	public string CPF { get; set; }
	public double Salario { get; set; }
}
mas neste caso estaríamos apenas repetindo código. Funcionário tem as mesmas propriedades do Diretor... e do Desenvovledor também terá. Para evitar repetição de código e relacionar dizer pro compilador que toda classe de Diretor é um Funcionário, podemos utilizar o conceito de Herança. No C# para especificar a herança usamos dois pontos, assim:
public class Diretor : Funcionario { }
Através desse código, podemos criar um objeto Diretor e estanciar as mesmas propriedades de um funcionário:
Diretor camila = new Diretor();
camila.Nome = "Camila";
camila.CPF = "123.456.789-01";
camila.Salario = 1000;
E os métodos? Também são compartilhados? Sim! Por exemplo:
public class Funcionario
{
	public string Nome { get; set; }
	public string CPF { get; set; }
	public double Salario { get; set; }
    
	public void AumentarSalario()
	{
		Salario *= 1.15; //aumento de 15%
	}
}

public class Diretor : Funcionario
{
	public void AumentarSalario()
	{
		Salario *= 1.11; //aumento de 11%
	}
}
Supondo que o aumento do Diretor é diferente de um funcionário comum, poderíamos criar este código, porém a função AumentarSalario() não será sobrescrita se tivermos o seguinte código:
Funcionario funcionario = new Diretor();
Mesmo sendo completamente compilável e correto, a função AumentarSalario não estará correta. Para sobrescrever funções, em caso de herança em C#, é necessário tornar a função da classe mais genérica virtual. Dessa forma sinalizamos para o compilador que ela pode ser sobrescrita por outras classes... e na classe que herda temos que especificar que a função será sobrescrita. Para isso usamos as palavras reservadas "virtual" e "override".
public class Funcionario
{
	(...)
	public virtual void AumentarSalario()
	{
		Salario *= 1.15; //aumento de 15%
	}
}

public class Diretor : Funcionario
{
	public override void AumentarSalario()
	{
		Salario *= 1.11; //aumento de 11%
	}
}
Dessa forma garantimos que o código sempre retorne a porcentagem correta de aumento para o Diretor. Mas, todo funcionário sempre terá um tipo específico, não é mesmo? Então instanciar a classe funcionário pode gerar um problema, pois não saberemos qual funcionário se trata. Gostaríamos de sempre instaciar apenas as classes que herdam de funcionário. Em C#, para impedir que isso aconteça, tornamos a classe abstrata.
Classes abstratas são classes que servem como modelo para suas subclasses. Classes abstratas não podem ser instanciadas, apenas herdadas. Os métodos declarados na classe abstrata devem ser implementados nas subclasses (classes concretas).
Assim, impedimos que classes genéricas sejam instânciadas. Porém, quando uma classe se torna abstrata, como vimos na descrição, ela não deve implementar métodos, apenas indicar métodos que devem ser implementados nas classes que herdam dela, dessa forma, o nosso novo código será:
public abstract class Funcionario
{
	(...)
	public abstract void AumentarSalario();
}

public class Diretor : Funcionario
{
	public override void AumentarSalario()
	{
		Salario *= 1.11; //aumento de 11%
	}
}
Existe também a possibilidade, no C#, do uso da palavra reservada "base" quando desejamos passar informações da subclasse para a classe abstrata. Podemos utilizar o exemplo no caso de termos construtores:
public abstract class Funcionario
{
	(...)
	public Funcionario(string cpf, double salario)
	{
		CPF = cpf;
		Salario = salario;
	}	
	public abstract void AumentarSalario();
}

public class Diretor : Funcionario
{
	public Diretor(string cpf) : base(cpf, 5000)
	{ }
        
	public override void AumentarSalario()
	{
		Salario *= 1.11; //aumento de 11%
	}
}
No código acima, definimos que toda vez que instaciamos uma classe que herda de Funcionario deve ser especificado, obrigatoriamente um CPF e um salário. E fizemos ainda mais, todo Diretor da empresa tem o salário inicial de 5000. Dessa forma, não precisamos escrever o construtor em todas as subclasses, podemos passar os valores para funcionário utilizado a palavra reservada base. Mas, vamos imaginar que nosso sistema precisa de modificações. A empresa decidiu dar acesso externo a clientes da empresa. E além disso, é necessário implementar uma forma de autenticação para esses clientes e para Diretores da empresa, afim de acessar dados específicos apenas visiveis para eles. Como fazer então? Teoricamente seria possivel criar uma outra classe abstrada chamada Autenticação e tanto o Cliente quanto o Diretor herdariam dessa classe. Porém, com o Diretor teríamos duas heranças, e em C# não é permitido ter heranças multiplas... então, temos que pensar em outra solução. Um novo conceito que pode nos ajudar nesta tarefa é o de interfaces:
Interfaces definem o que uma classe deve fazer e não como, podendo se assimilar a um "contrato assinado". Dessa forma, as interfaces não possuem a implementação de métodos (apenas os declaram), deixando a classe responsável por usa implementação.
Uma interface, diferente da herança, pode ser utilizada por diversas classes e podemos ter multiplas interfaces dentro de uma "subclasse". Quando usamos interface o conceito de subclasse não existe mais, pois a classe que implementa uma interface "assina um compromisso" de implementar os métodos que a interface definiu. Então, voltando ao exemplo, podemos criar uma interface para Autenticação:
public interface IAutenticavel
{
	bool Autenticar(string senha);
}
E agora a classe Diretor pode implementar esta interface:
public class Diretor : IAutenticavel, Funcionario
{
	public string Senha { get; set; }
	(...)
	public bool Autenticar(string senha)
	{
		return Senha == senha;
	}    
}

public class ClienteExterno : IAutenticavel
{
	public String Nome { get; set; }
	public String Senha { get; set; }
	public bool Autenticar(string senha)
	{
		return Senha == senha;
	}
}
A implementação do método Autenticar pode ser completamente diferente nas duas classes, inclusve podem retornar acesso a diferentes áreas, foi apenas uma conincidência (e praticidade) aparecerem iguais!

Como compilar uma aplicação C# sem o Visual Studio

A partir do Windows XP, todos os computadores com Windows possuem o compiladore instalado nativamente.

Por exemplo, neste caminho: C:\Windows\Microsoft.NET\Framework\v4.0.30319

Esta pasta possuí todos os arquivos que a VM (CLR) precisa para rodar aplicações .net na versão 4.0.30319, inclusive um arquivo chamado "csc.exe" que é uma abreviação para CSharp Compiler.

Tendo aprendido isso, podemos abrir o bloco de notas e colar o seguinte código e salve como txt, de preferencia em uma nova pasta:

using System;
class Programa
{
	static void Main(string[] args)
    {
		Console.WriteLine("Olá mundo");
    }
}

Abrir o CMD, entrar no ocal onde o arquivo foi salvo. Dentro da nova pasta onde salvamos o arquivo. digite o caminho para o compilador do C#: C:\Windows\Microsoft.NET\Framework\v4.0.30319\csc.exe NOMEDOARQUIVO.txt.

Pressione Enter.

Se formos olhar o que tem dentro do novo diretório, vamos encontrar um novo arquivo NOMEDOARQUIVO.exe.

Se voltarmos ao CMD e digitar NOMEDOARQUIVO.exe aparecerá o "Olá Mundo" que escrevemos!

C# - Considerações iniciais

Antes de começar a escrever códigos em C# é de bom tom entender o ecossitema da Microsoft suporta esta linguagem!

Antigamente, para se reescrever uma aplicação de C para VB, por exemplo, não bastava reescrever a aplicação, era necessário reescrever a biblioteca desta aplicação também. E para o caso de mudar o Sistema Operacional (SO)? Tinha que reescrever a aplicação e a biblioteca para cada SO.

Daí, começando pelo SO, a Microsoft desenvolveu uma Máquina Virtual (Virtual Machina - VM) que roda em qualquer SO (Sim, assim como Java). Dessa forma, escreveremos a aplicação para a VM e não para a máquina real (com memória RAM, processador físico.. cooler)

Dessa forma, não precisamos mais de bibliotecas e aplicações especificas para cada linguagem, podemos ter uma biblioteca e uma aplicação genérica, chamada de MSIL (Microsoft Intermediate Language), que compilará nosso código para a VM.

Em outras palavras, podemos escrever códigos em C#, VB, F# e eles serão compilados para uma aplicação escrita em MSIL que conversará com uma biblioteca MSIL. A VM conhece essa biblioteca e qualquer SO pode implementar nossa VM, sem complicações. Se quisermos ter um projeto escrito metade em C# e metade em VB, podemos, pois ambos são compilados para MSIL.

Dessa forma, temos essa hierarquia:

  • Linguagens: C#, VB, F# ...
  • Aplicação MSIL
  • Biblioteca MSIL
  • Máquina Virtual
  • Sistemas Operacionais (Windows, Linux, PS4...)
Agora, basta conhecermos os nomes específicos de cada uma das hierarquias no mundo C#. A Máquina Virtual é chamada de CLR - Common Language  Runtime. A Biblioteca MSIL é chamada de .NET Framework e a Aplicação MSIL é a aplicação .NET.

Num exemplo, o código escrito em C#:

Console.WriteLine("Olá mundo");

É compilado para um formato MSIL, tipo esse:

nop 
ldstr       "Olá mundo"
call        System.Console.WriteLine
nop  
ret

Toda linguagem .NET será compilada para esse mesmo formato que é excecutado pela CLR (ou VM). E agora, no momento da execução desse código a VM vai converter o MSIL em linguagem de máquina (linguagem que o processador entende - aquele mesmo da AMD ou Intel).

E daí vem mais um conceito, o Just-In-Time Compiler (ou Jitter) que significa que o compilador apenas executa código no momento que aplicação roda.. dessa forma, o CLR consegue compilar o código para o processador específico que a aplicação roda."

Estruturas de Repetição - While

Estruturas de repetição fazem parte do pacote básico de quem está aprendendo a programar, e ajudam no controle do fluxo de execução de determinada parte do código. É muito útil e bastante utilizado para... hum.. tudo. :)

Enquanto (while)

A estrutura mais simples, executa uma ação enquanto determinada condição for verdadeira.


Em C++/C:

while (condição)
{
    código;
    código;
    (...)
}


Podemos observar que logo depois do while, vem uma condição. Essa condição é verificada antes de entrar no "laço" de repetição e só vai parar de repetir quanto a condição se tornar falsa.
Por exemplo, vamos imprimir os números na tela começando do 100 e terminando no 0.



Entendendo o programa:


Começamos declarando uma variável inteira i e atribuímos o valor 100 a ela.
A linha seguinte é o inicio do while, a condição que usamos de parada é i ser menor ou igual a zero. Se for verdadeiro, o programa vai executar o que esta entre as chaves {}, caso for negativo o programa vai "pular" o que está entre chaves e executar o que tiver depois, se não tiver nada, é o fim do programa.
Como 100 é maior ou igual a 0, ele entra no loop. A primeira instrução é imprimir na tela o valor da variável i e quebrar uma linha (endl).
A segunda instrução no loop atribui um novo valor pra variável i, o que é importantíssimo pois ninguém quer cair num loop infinito, não é?!
Então i receberá o seu próprio valor subtraído de uma unidade, vamos fazer a conta:
i = 100 - 1;
i = 99;
Novo valor de i: 99!
Agora, o programa volta no while, e verifica a condição de novo.
(99 é maior ou igual a zero?)
É! Então ele executa as duas instruções de novo, imprimir o valor de i na tela e decrementar uma unidade do mesmo.
Isso vai acontecer até que i chegue a -1, em que a condição não será verificada e sairá do loop!
O return 0 é a instrução logo depois do loop que indica o fim do programa.

Outra possibilidade: Faça... Enquanto.

Outra forma de se utilizar o enquanto (while) é colocando sua condição de verificação (também chamada de flag) no final. Assim, o que estiver dentro do loop será executado uma vez e só se repetirá caso a condição seja verdadeira.  Dá pra ver claramente a diferença! O primeiro testa e depois executa este executa e depois testa. 


do {
   Código;
   Código;
} while(condição);
Pode ser utilizado para realizar cadastro de clientes, por exemplo. O programa pede os dados do cliente e solicita confirmação se deseja incluir mais... Enquanto o usuário desejar incluir mais cliente o programa não sairá do Loop. Essa condição pode ser enquanto o usuário não digitar zero ou clicando no botão de "ok"/"cancelar", etc
Qualquer coisa que seja fácil de implementar e você consiga fazer funcionar!!