howter

Roteador para organizar a execução de código JavaScript.


License
MIT
Install
bower install howter

Documentation

Howter

Howter é um pequeno roteador criado para organizar a execução do código JavaScript em aplicações web.

Instalação

Para utilizá-lo, pode-se usar uma das seguintes opções:

Em seguida, basta carregar um dos arquivos do diretório dist através de uma tag <script>:

<!-- Código completo -->
<script src="caminho/completo/até/howter.js"></script>

<!-- Versão minificada -->
<script src="caminho/completo/até/howter.min.js"></script>

Funcionamento básico

Incluída a tag <script>, Howter ficará disponível através de uma variável global chamada (adivinhe) Howter. Com ele, seu código é dividido em rotas e callbacks. Na aplicação mais simples possível, você pode usar rotas para organizar a execução do JavaScript de acordo com a URL acessada pelo usuário. Você pode, por exemplo, perguntar o nome do visitante somente quando ele acessar http://example.com/welcome:

(function (h) {

    h.route('/welcome', function () {
        var name = prompt('What is your name?', 'Harry Potter');

        alert('Hello, ' + name + '!');
    });

    h.dispatch(window.location.pathname);

}(Howter));

Como você pode ver pelo exemplo, o método Howter.route recebe dois argumentos, justamente a rota ("/welcome") e o callback, cuja única função é encapsular o código JavaScript que deve ser executado quando a rota for correspondida.

Quando o método Howter.dispatch(path) é chamado, seu argumento path é comparado com cada uma das rotas definidas. Sempre que uma rota correspondente é encontrada, o callback é executado. No exemplo anterior, isso significa que o prompt perguntando o nome do usuário só será exibido quando window.location.pathname for "/welcome".

Nota: o método dispatch pode ser chamado quantas vezes for necessário e com qualquer valor de path. Você pode, por exemplo, usar uma rota para encapsular instruções executadas diversas vezes e executá-la arbitrariamente sempre que necessário com Howter.dispatch('/common-functions').

Para adicionar funcionalidades específicas a outras URLs, basta definir outras rotas:

(function (h) {

    h.route('/welcome', function () {
        var name = prompt('What is your name?', 'Harry Potter');

        alert('Hello, ' + name + '!');
    });

    h.route('/contact', function () {
        alert('You reached the contact page!');
    }).route('/error', function () { // Rotas encadeadas!
        alert('You reached the error page!');
    });

    h.dispatch(window.location.pathname);

}(Howter));

Rotas com múltiplos caminhos

Às vezes, é necessário executar o mesmo código JavaScript em duas rotas diferentes. Ao invés de definir duas rotas distintas, podemos passar um array de caminhos ao método route:

h.route(['/users/list', '/products/list'], function () {
    // ...
});

Nesse caso, o callback será executado tanto em http://example.com/users/list quanto em http://example.com/products/list.

Parâmetros nomeados

Imagine que você queira criar uma rota para páginas de perfil de usuário cujas URLs estão no formato http://example.com/profile/<username>. Mesmo com rotas de múltiplos caminhos, não faz muito sentido ter um caminho para cada nome de usuário possível, certo? Seria um array infinito!

Para contornar isso, usamos parâmetros nomeados:

h.route('/profile/:username', function (context) {
    alert('Hello, ' + context.params.username + '!');
});

Graças a esse trecho variável da URL, o callback será executado com qualquer nome de usuário. Pode-se usar quantos parâmetros nomeados forem necessários e acessar seus valores através do parâmetro context, uma instância da classe Howter.Context sempre passada como argumento do callback (mesmo quando o omitimos, como nos exemplos anteriores).

A propriedade do contexto que contém todos os parâmetros nomeados pode ser acessada tanto através de context.params quanto de this.params.

Caracter coringa

Caracteres coringas são úteis para vincular a execução de callbacks à parte inicial de uma rota, independentemente de como ela termine. Você pode, por exemplo, determinar que todas as rotas iniciadas por "/admin" devam executar determinado código:

h.route('/admin/*', function () {
    // ...
});

O asterisco é usado como caracter coringa e corresponderá a qualquer combinação de caracteres, repassados ao callback no parâmetro nomeado this.params.splat.

Prefixos

Quando o número de suas rotas começar a crescer, pode ser uma boa ideia agrupá-las por prefixo. Para isso, use o método Howter.prefix:

h.prefix('/admin', function () {
    // A rota abaixo equivale a /admin/users
    h.route('/users', function () {
        // ...
    });

    // A rota abaixo equivale a /admin/products
    h.route('/products', function () {
        // ...
    });

    h.prefix('/foo', function () {
        // A rota abaixo equivale a /admin/foo/bar
        h.route('/bar', function () {
            // ...
        });
    });
});

Você pode definir também um prefixo universal que será injetado antes de todas as rotas. Em rotas baseadas em URL, por exemplo, essa propriedade (Howter.root) pode ser setada assincronamente no HTML e evitar que você tenha que alterar todas as rotas quando a aplicação for movida para um subdiretório:

<script>Howter = window.Howter || {}; Howter.root = '/subdirectory';</script>

Expressões regulares

TBD.

Rotas estendidas

É possível estender ou mesmo redefinir completamente um callback usando o método Howter.extend(extension). Para ver na prática sua utilidade, vamos estender nosso exemplo de parâmetros nomeados:

h.route('/profile/:username', function (context) {
    alert('Hello, ' + context.params.username + '!');
}, 'profile');

Note que adicionamos um terceiro parâmetro à declaração da rota: um nome. Isso é necessário porque somente nomeando a rota podemos recuperá-la e estendê-la:

h.route('profile').extend(function (original) {
    this.callback = function() {
        this.params.username = 'Amazing ' + this.params.username;

        original.call(this, this);
    };
});

A extensão é uma função que recebe o callback original como primeiro argumento e seu contexto na variável this. O exemplo acima altera o contexto concatenando a string "Amazing " ao parâmetro name e depois chama o callback original, recebido no argumento original.

Compartilhamento de dados

TBD.