Learn/learn
Aprender
Esta página é um guia para aprender Flight. Cobre os fundamentos do framework e como usá-lo.
Roteamento
O roteamento no Flight é feito combinando um padrão de URL com uma função de retorno de chamada.
Flight::route('/', function(){
echo 'Olá, mundo!';
});
A função de retorno de chamada pode ser qualquer objeto que seja chamado. Então você pode usar uma função regular:
function hello(){
echo 'Olá, mundo!';
}
Flight::route('/', 'hello');
Ou um método de classe:
class Greeting {
public static function hello() {
echo 'Olá, mundo!';
}
}
Flight::route('/', array('Greeting','hello'));
Ou um método de objeto:
class Greeting
{
public function __construct() {
$this->name = 'John Doe';
}
public function hello() {
echo "Olá, {$this->name}!";
}
}
$greeting = new Greeting();
Flight::route('/', array($greeting, 'hello'));
As rotas são combinadas na ordem em que são definidas. A primeira rota a combinar com uma solicitação será invocada.
Roteamento por Método
Por padrão, os padrões de rota são combinados com todos os métodos de solicitação. Você pode responder a métodos específicos colocando um identificador antes da URL.
Flight::route('GET /', function(){
echo 'Recebi uma solicitação GET.';
});
Flight::route('POST /', function(){
echo 'Recebi uma solicitação POST.';
});
Você também pode mapear múltiplos métodos para uma única função de retorno de chamada usando um delimitador |
:
Flight::route('GET|POST /', function(){
echo 'Recebi uma solicitação GET ou POST.';
});
Expressões Regulares
Você pode usar expressões regulares em suas rotas:
Flight::route('/user/[0-9]+', function(){
// Isso combinará /user/1234
});
Parâmetros Nomeados
Você pode especificar parâmetros nomeados em suas rotas que serão passados para a sua função de retorno de chamada.
Flight::route('/@name/@id', function($name, $id){
echo "Olá, $name ($id)!";
});
Você também pode incluir expressões regulares com seus parâmetros nomeados usando o delimitador :
:
Flight::route('/@name/@id:[0-9]{3}', function($name, $id){
// Isso combinará /bob/123
// Mas não combinará /bob/12345
});
Parâmetros Opcionais
Você pode especificar parâmetros nomeados que são opcionais para a correspondência envolvendo segmentos entre parênteses.
Flight::route('/blog(/@year(/@month(/@day)))', function($year, $month, $day){
// Isso combinará os seguintes URLs:
// /blog/2012/12/10
// /blog/2012/12
// /blog/2012
// /blog
});
Quaisquer parâmetros opcionais que não forem correspondidos serão passados como NULL.
Wilcards
A correspondência é feita somente em segmentos de URL individuais. Se você quiser combinar múltiplos segmentos, pode usar o wildcard *
.
Flight::route('/blog/*', function(){
// Isso combinará /blog/2000/02/01
});
Para direcionar todas as solicitações a uma única função de retorno de chamada, você pode fazer:
Flight::route('*', function(){
// Fazer algo
});
Passagem
Você pode passar a execução para a próxima rota correspondente retornando true
da sua função de retorno de chamada.
Flight::route('/user/@name', function($name){
// Verificar alguma condição
if ($name != "Bob") {
// Continuar para a próxima rota
return true;
}
});
Flight::route('/user/*', function(){
// Isso será chamado
});
Informações de Rota
Se você quiser inspecionar as informações da rota correspondente, pode solicitar que o objeto da rota seja passado para sua função de retorno de chamada passando true
como o terceiro parâmetro no método de rota. O objeto da rota sempre será o último parâmetro passado para sua função de retorno de chamada.
Flight::route('/', function($route){
// Array de métodos HTTP correspondidos
$route->methods;
// Array de parâmetros nomeados
$route->params;
// Expressão regular correspondente
$route->regex;
// Contém o conteúdo de qualquer '*' usado no padrão da URL
$route->splat;
}, true);
Agrupamento de Rotas
Pode haver momentos em que você queira agrupar rotas relacionadas (como /api/v1
).
Você pode fazer isso usando o método group
:
Flight::group('/api/v1', function () {
Flight::route('/users', function () {
// Combina /api/v1/users
});
Flight::route('/posts', function () {
// Combina /api/v1/posts
});
});
Você pode até aninhar grupos de grupos:
Flight::group('/api', function () {
Flight::group('/v1', function () {
// Flight::get() obtém variáveis, não define uma rota! Veja o contexto de objeto abaixo
Flight::route('GET /users', function () {
// Combina GET /api/v1/users
});
Flight::post('/posts', function () {
// Combina POST /api/v1/posts
});
Flight::put('/posts/1', function () {
// Combina PUT /api/v1/posts
});
});
Flight::group('/v2', function () {
// Flight::get() obtém variáveis, não define uma rota! Veja o contexto de objeto abaixo
Flight::route('GET /users', function () {
// Combina GET /api/v2/users
});
});
});
Agrupamento com Contexto de Objeto
Você ainda pode usar o agrupamento de rotas com o objeto Engine
da seguinte maneira:
$app = new \flight\Engine();
$app->group('/api/v1', function (Router $router) {
$router->get('/users', function () {
// Combina GET /api/v1/users
});
$router->post('/posts', function () {
// Combina POST /api/v1/posts
});
});
Alias de Rota
Você pode atribuir um alias a uma rota, para que a URL possa ser gerada dinamicamente mais tarde em seu código (como um template, por exemplo).
Flight::route('/users/@id', function($id) { echo 'usuário:'.$id; }, false, 'user_view');
// mais tarde em algum lugar do código
Flight::getUrl('user_view', [ 'id' => 5 ]); // retornará '/users/5'
Isso é especialmente útil se sua URL mudar. No exemplo acima, digamos que os usuários foram movidos para /admin/users/@id
em vez disso.
Com o alias em vigor, você não precisa mudar em nenhum lugar onde você faz referência ao alias, porque o alias agora retornará /admin/users/5
, como no
exemplo acima.
A aliasação de rota ainda funciona em grupos também:
Flight::group('/users', function() {
Flight::route('/@id', function($id) { echo 'usuário:'.$id; }, false, 'user_view');
});
// mais tarde em algum lugar do código
Flight::getUrl('user_view', [ 'id' => 5 ]); // retornará '/users/5'
Estendendo
Flight foi projetado para ser um framework extensível. O framework vem com um conjunto de métodos e componentes padrão, mas permite que você mapeie seus próprios métodos, registre suas próprias classes ou até mesmo sobrescreva classes e métodos existentes.
Mapeamento de Métodos
Para mapear seu próprio método personalizado, você usa a função map
:
// Mapeie seu método
Flight::map('hello', function($name){
echo "Olá $name!";
});
// Chame seu método personalizado
Flight::hello('Bob');
Registro de Classes
Para registrar sua própria classe, você usa a função register
:
// Registre sua classe
Flight::register('user', 'User');
// Obtenha uma instância da sua classe
$user = Flight::user();
O método de registro também permite que você passe parâmetros para o construtor da sua classe. Assim, quando você carrega sua classe personalizada, ela virá pré-inicializada. Você pode definir os parâmetros do construtor passando um array adicional. Aqui está um exemplo de carregar uma conexão de banco de dados:
// Registre a classe com parâmetros do construtor
Flight::register('db', 'PDO', array('mysql:host=localhost;dbname=test','user','pass'));
// Obtenha uma instância da sua classe
// Isso criará um objeto com os parâmetros definidos
//
// new PDO('mysql:host=localhost;dbname=test','user','pass');
//
$db = Flight::db();
Se você passar um parâmetro de callback adicional, ele será executado imediatamente após a construção da classe. Isso permite que você execute qualquer procedimento de configuração para o seu novo objeto. A função de retorno de chamada recebe um parâmetro, uma instância do novo objeto.
// A função de retorno de chamada receberá o objeto que foi construído
Flight::register('db', 'PDO', array('mysql:host=localhost;dbname=test','user','pass'),
function($db){
$db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
}
);
Por padrão, toda vez que você carrega sua classe, receberá uma instância compartilhada.
Para obter uma nova instância de uma classe, simplesmente passe false
como um parâmetro:
// Instância compartilhada da classe
$shared = Flight::db();
// Nova instância da classe
$new = Flight::db(false);
Lembre-se de que os métodos mapeados têm precedência sobre as classes registradas. Se você declara ambos usando o mesmo nome, apenas o método mapeado será invocado.
Sobrescrevendo
Flight permite que você sobrescreva sua funcionalidade padrão para atender às suas próprias necessidades, sem ter que modificar nenhum código.
Por exemplo, quando o Flight não consegue combinar uma URL com uma rota, ele invoca o método notFound
que envia uma resposta genérica HTTP 404
. Você pode sobrescrever esse comportamento
usando o método map
:
Flight::map('notFound', function(){
// Exibir página 404 personalizada
include 'errors/404.html';
});
Flight também permite que você substitua componentes principais do framework. Por exemplo, você pode substituir a classe Router padrão por sua própria classe personalizada:
// Registre sua classe personalizada
Flight::register('router', 'MyRouter');
// Quando o Flight carrega a instância do Router, ele carregará sua classe
$myrouter = Flight::router();
Métodos do framework como map
e register
no entanto não podem ser sobrescritos. Você
receberá um erro se tentar fazer isso.
Filtrando
Flight permite que você filtre métodos antes e depois que eles sejam chamados. Não há ganchos predefinidos que você precisa memorizar. Você pode filtrar qualquer um dos métodos padrão do framework assim como quaisquer métodos personalizados que você tenha mapeado.
Uma função de filtro se parece com isso:
function(&$params, &$output) {
// Código de filtro
}
Usando as variáveis passadas, você pode manipular os parâmetros de entrada e/ou a saída.
Você pode ter um filtro rodando antes de um método fazendo:
Flight::before('start', function(&$params, &$output){
// Fazer algo
});
Você pode ter um filtro rodando depois de um método fazendo:
Flight::after('start', function(&$params, &$output){
// Fazer algo
});
Você pode adicionar quantos filtros quiser a qualquer método. Eles serão chamados na ordem em que foram declarados.
Aqui está um exemplo do processo de filtragem:
// Mapeie um método personalizado
Flight::map('hello', function($name){
return "Olá, $name!";
});
// Adicione um filtro antes
Flight::before('hello', function(&$params, &$output){
// Manipule o parâmetro
$params[0] = 'Fred';
});
// Adicione um filtro depois
Flight::after('hello', function(&$params, &$output){
// Manipule a saída
$output .= " Tenha um bom dia!";
});
// Invocar o método personalizado
echo Flight::hello('Bob');
Isso deve exibir:
Olá Fred! Tenha um bom dia!
Se você definiu múltiplos filtros, pode interromper a cadeia retornando false
em qualquer uma das suas funções de filtro:
Flight::before('start', function(&$params, &$output){
echo 'um';
});
Flight::before('start', function(&$params, &$output){
echo 'dois';
// Isso interromperá a cadeia
return false;
});
// Isso não será chamado
Flight::before('start', function(&$params, &$output){
echo 'três';
});
Nota: métodos principais como map
e register
não podem ser filtrados porque são
chamados diretamente e não invocados dinamicamente.
Variáveis
Flight permite que você salve variáveis para que possam ser usadas em qualquer lugar de sua aplicação.
// Salve sua variável
Flight::set('id', 123);
// Em outro lugar da sua aplicação
$id = Flight::get('id');
Para ver se uma variável foi definida, você pode fazer:
if (Flight::has('id')) {
// Fazer algo
}
Você pode limpar uma variável fazendo:
// Limpa a variável id
Flight::clear('id');
// Limpa todas as variáveis
Flight::clear();
Flight também usa variáveis para fins de configuração.
Flight::set('flight.log_errors', true);
Visões
Flight fornece algumas funcionalidades de template básicas por padrão. Para exibir um modelo de visão, chame o método render
com o nome do arquivo de modelo e dados de modelo opcionais:
Flight::render('hello.php', array('name' => 'Bob'));
Os dados do modelo que você passa são automaticamente injetados no modelo e podem ser referenciados como uma variável local. Os arquivos de modelo são simplesmente arquivos PHP. Se o conteúdo do arquivo de modelo hello.php
for:
Olá, '<?php echo $name; ?>'!
A saída seria:
Olá, Bob!
Você também pode definir manualmente variáveis de visão usando o método set:
Flight::view()->set('name', 'Bob');
A variável name
agora está disponível em todas as suas visões. Portanto, você pode simplesmente fazer:
Flight::render('hello');
Note que ao especificar o nome do modelo no método render, você pode deixar de fora a extensão .php
.
Por padrão, o Flight procurará um diretório views
para arquivos de modelo. Você pode definir um caminho alternativo para seus modelos configurando o seguinte:
Flight::set('flight.views.path', '/caminho/para/views');
Layouts
É comum que os sites tenham um único arquivo de layout de modelo com conteúdo intercambiável. Para renderizar conteúdo a ser usado em um layout, você pode passar um parâmetro opcional para o método render
.
Flight::render('header', array('heading' => 'Olá'), 'header_content');
Flight::render('body', array('body' => 'Mundo'), 'body_content');
Sua visão terá então variáveis salvas chamadas header_content
e body_content
.
Você pode então renderizar seu layout fazendo:
Flight::render('layout', array('title' => 'Página Inicial'));
Se os arquivos de modelo se parecerem com isto:
header.php
:
<h1><?php echo $heading; ?></h1>
body.php
:
<div><?php echo $body; ?></div>
layout.php
:
<html>
<head>
<title><?php echo $title; ?></title>
</head>
<body>
<?php echo $header_content; ?>
<?php echo $body_content; ?>
</body>
</html>
A saída seria:
<html>
<head>
<title>Página Inicial</title>
</head>
<body>
<h1>Olá</h1>
<div>Mundo</div>
</body>
</html>
Visões Personalizadas
Flight permite que você substitua o mecanismo de visualização padrão simplesmente registrando sua própria classe de visão. Aqui está como você usaria o Smarty mecanismo de template para suas visões:
// Carregue a biblioteca Smarty
require './Smarty/libs/Smarty.class.php';
// Registre o Smarty como a classe de visão
// Também passe uma função de retorno de chamada para configurar o Smarty ao carregar
Flight::register('view', 'Smarty', array(), function($smarty){
$smarty->template_dir = './templates/';
$smarty->compile_dir = './templates_c/';
$smarty->config_dir = './config/';
$smarty->cache_dir = './cache/';
});
// Atribua dados de template
Flight::view()->assign('name', 'Bob');
// Exiba o template
Flight::view()->display('hello.tpl');
Para completar, você também deve sobrescrever o método render padrão do Flight:
Flight::map('render', function($template, $data){
Flight::view()->assign($data);
Flight::view()->display($template);
});
Tratamento de Erros
Erros e Exceções
Todos os erros e exceções são capturados pelo Flight e passados para o método error
.
O comportamento padrão é enviar uma resposta genérica HTTP 500 Internal Server Error
com algumas informações sobre o erro.
Você pode sobrescrever esse comportamento para suas próprias necessidades:
Flight::map('error', function(Exception $ex){
// Tratar erro
echo $ex->getTraceAsString();
});
Por padrão, os erros não são registrados no servidor web. Você pode habilitar isso mudando a configuração:
Flight::set('flight.log_errors', true);
Não Encontrado
Quando uma URL não pode ser encontrada, o Flight chama o método notFound
. O comportamento padrão é enviar uma resposta HTTP 404 Not Found
com uma mensagem simples.
Você pode sobrescrever esse comportamento para suas próprias necessidades:
Flight::map('notFound', function(){
// Tratar não encontrado
});
Redirecionamentos
Você pode redirecionar a solicitação atual usando o método redirect
e passando
uma nova URL:
Flight::redirect('/nova/localizacao');
Por padrão, o Flight envia um código de status HTTP 303. Você pode opcionalmente definir um código personalizado:
Flight::redirect('/nova/localizacao', 401);
Solicitações
Flight encapsula a solicitação HTTP em um único objeto, que pode ser acessado fazendo:
$request = Flight::request();
O objeto de solicitação fornece as seguintes propriedades:
url - A URL sendo solicitada
base - O subdiretório pai da URL
method - O método de solicitação (GET, POST, PUT, DELETE)
referrer - A URL de referência
ip - Endereço IP do cliente
ajax - Se a solicitação é uma solicitação AJAX
scheme - O protocolo do servidor (http, https)
user_agent - Informações do navegador
type - O tipo de conteúdo
length - O comprimento do conteúdo
query - Parâmetros da string de consulta
data - Dados post ou dados JSON
cookies - Dados de cookies
files - Arquivos enviados
secure - Se a conexão é segura
accept - Parâmetros de aceitação HTTP
proxy_ip - Endereço IP do proxy do cliente
Você pode acessar as propriedades query
, data
, cookies
e files
como arrays ou objetos.
Portanto, para obter um parâmetro da string de consulta, você pode fazer:
$id = Flight::request()->query['id'];
Ou você pode fazer:
$id = Flight::request()->query->id;
Corpo da Solicitação RAW
Para obter o corpo da solicitação HTTP raw, por exemplo, ao lidar com solicitações PUT, você pode fazer:
$body = Flight::request()->getBody();
Entrada JSON
Se você enviar uma solicitação com o tipo application/json
e os dados {"id": 123}
, estará disponível
a partir da propriedade data
:
$id = Flight::request()->data->id;
Parando
Você pode parar o framework a qualquer momento chamando o método halt
:
Flight::halt();
Você também pode especificar um código de status HTTP
opcional e uma mensagem:
Flight::halt(200, 'Volte logo...');
Chamar halt
descartará qualquer conteúdo de resposta até aquele ponto. Se você quiser parar
o framework e apresentar a resposta atual, use o método stop
:
Flight::stop();
Cache HTTP
Flight fornece suporte embutido para caching a nível HTTP. Se a condição de caching
for atendida, o Flight retornará uma resposta HTTP 304 Not Modified
. Da próxima vez que o
cliente solicitar o mesmo recurso, ele será solicitado a usar sua versão em cache local.
Última Modificação
Você pode usar o método lastModified
e passar um timestamp UNIX para definir a data
e hora em que uma página foi modificada pela última vez. O cliente continuará a usar seu cache até
que o valor da última modificação seja alterado.
Flight::route('/news', function(){
Flight::lastModified(1234567890);
echo 'Este conteúdo será armazenado em cache.';
});
ETag
A cache ETag
é semelhante à Última Modificação
, exceto que você pode especificar qualquer ID que
quiser para o recurso:
Flight::route('/news', function(){
Flight::etag('meu-id-unico');
echo 'Este conteúdo será armazenado em cache.';
});
Lembre-se de que chamar lastModified
ou etag
tanto define quanto verifica o
valor do cache. Se o valor do cache for o mesmo entre as solicitações, o Flight enviará imediatamente
uma resposta HTTP 304
e interromperá o processamento.
JSON
Flight oferece suporte para enviar respostas JSON e JSONP. Para enviar uma resposta JSON você passa alguns dados para serem codificados em JSON:
Flight::json(array('id' => 123));
Para solicitações JSONP, você pode opcionalmente passar o nome do parâmetro de consulta que está usando para definir sua função de retorno de chamada:
Flight::jsonp(array('id' => 123), 'q');
Assim, ao fazer uma solicitação GET usando ?q=my_func
, você deve receber a saída:
my_func({"id":123});
Se você não passar um nome de parâmetro de consulta, ele será definido como jsonp
.
Configuração
Você pode personalizar certos comportamentos do Flight definindo valores de configuração
através do método set
.
Flight::set('flight.log_errors', true);
A seguir está uma lista de todas as configurações de configuração disponíveis:
flight.base_url - Substitui a URL base da solicitação. (padrão: null)
flight.case_sensitive - Correspondência sensível a maiúsculas para URLs. (padrão: false)
flight.handle_errors - Permite que o Flight trate todos os erros internamente. (padrão: true)
flight.log_errors - Registra erros no arquivo de log de erros do servidor web. (padrão: false)
flight.views.path - Diretório contendo arquivos de template de visão. (padrão: ./views)
flight.views.extension - Extensão de arquivo de template de visão. (padrão: .php)
Métodos do Framework
Flight foi projetado para ser fácil de usar e entender. A seguir está o conjunto completo de métodos para o framework. Consiste em métodos principais, que são métodos estáticos regulares, e métodos extensíveis, que são métodos mapeados que podem ser filtrados ou sobrescritos.
Métodos Principais
Flight::map(string $name, callable $callback, bool $pass_route = false) // Cria um método de framework personalizado.
Flight::register(string $name, string $class, array $params = [], ?callable $callback = null) // Registra uma classe a um método de framework.
Flight::before(string $name, callable $callback) // Adiciona um filtro antes de um método de framework.
Flight::after(string $name, callable $callback) // Adiciona um filtro depois de um método de framework.
Flight::path(string $path) // Adiciona um caminho para carregamento automático de classes.
Flight::get(string $key) // Obtém uma variável.
Flight::set(string $key, mixed $value) // Define uma variável.
Flight::has(string $key) // Verifica se uma variável está definida.
Flight::clear(array|string $key = []) // Limpa uma variável.
Flight::init() // Inicializa o framework com suas configurações padrão.
Flight::app() // Obtém a instância do objeto de aplicativo
Métodos Extensíveis
Flight::start() // Inicia o framework.
Flight::stop() // Para o framework e envia uma resposta.
Flight::halt(int $code = 200, string $message = '') // Para o framework com um código de status e mensagem opcionais.
Flight::route(string $pattern, callable $callback, bool $pass_route = false) // Mapeia um padrão de URL a uma função de retorno de chamada.
Flight::group(string $pattern, callable $callback) // Cria agrupamento para URLs, o padrão deve ser uma string.
Flight::redirect(string $url, int $code) // Redireciona para outra URL.
Flight::render(string $file, array $data, ?string $key = null) // Renderiza um arquivo de template.
Flight::error(Throwable $error) // Envia uma resposta HTTP 500.
Flight::notFound() // Envia uma resposta HTTP 404.
Flight::etag(string $id, string $type = 'string') // Realiza caching ETag HTTP.
Flight::lastModified(int $time) // Realiza caching HTTP de última modificação.
Flight::json(mixed $data, int $code = 200, bool $encode = true, string $charset = 'utf8', int $option) // Envia uma resposta JSON.
Flight::jsonp(mixed $data, string $param = 'jsonp', int $code = 200, bool $encode = true, string $charset = 'utf8', int $option) // Envia uma resposta JSONP.
Quaisquer métodos personalizados adicionados com map
e register
também podem ser filtrados.
Instância do Framework
Em vez de executar o Flight como uma classe estática global, você pode optar por executá-lo como uma instância de objeto.
require 'flight/autoload.php';
use flight\Engine;
$app = new Engine();
$app->route('/', function(){
echo 'Olá, mundo!';
});
$app->start();
Assim, em vez de chamar o método estático, você chamaria o método da instância com o mesmo nome no objeto Engine.
Install
Instalação
1. Baixe os arquivos.
Se você estiver usando Composer, pode executar o seguinte comando:
composer require flightphp/core
OU você pode baixá-los diretamente e extrair para o seu diretório web.
2. Configure seu servidor web.
Para Apache, edite seu arquivo .htaccess
com o seguinte:
RewriteEngine On
RewriteCond %{REQUEST_FILENAME} !-f
RewriteCond %{REQUEST_FILENAME} !-d
RewriteRule ^(.*)$ index.php [QSA,L]
Nota: Se você precisar usar flight em um subdiretório, adicione a linha
RewriteBase /subdir/
logo apósRewriteEngine On
. Nota: Se você quiser proteger todos os arquivos do servidor, como um arquivo db ou env. Coloque isso no seu arquivo.htaccess
:
RewriteEngine On
RewriteRule ^(.*)$ index.php
Para Nginx, adicione o seguinte à sua declaração de servidor:
server {
location / {
try_files $uri $uri/ /index.php;
}
}
3. Crie seu arquivo index.php
.
Primeiro, inclua o framework.
require 'flight/Flight.php';
Se você estiver usando Composer, execute o autoloader em vez disso.
require 'vendor/autoload.php';
Então, defina uma rota e atribua uma função para lidar com a solicitação.
Flight::route('/', function () {
echo 'hello world!';
});
Finalmente, inicie o framework.
Flight::start();
About
O que é Flight?
Flight é um framework rápido, simples e extensível para PHP.
Flight permite que você construa aplicações web RESTful de forma rápida e fácil.
require 'flight/Flight.php';
// Define a rota para a raiz
Flight::route('/', function(){
echo 'hello world!';
});
// Inicia o Flight
Flight::start();
Requisitos
Flight requer PHP 7.4 ou superior.
Licença
Flight é liberado sob a licença MIT.
Comunidade
Estamos no Matrix! Converse conosco em #flight-php-framework:matrix.org.
Contribuindo
Este site está hospedado no Github.
Atualizações e traduções de idiomas são bem-vindas.