quarta-feira, 1 de fevereiro de 2012

Javascript patters, antipatterns and performance tips

quarta-feira, 7 de dezembro de 2011

Creating your own PEAR channel using GitHub

Every PHP developer always dreamed about having his own PEAR channel, in this post I'll show you guys how to create it. Lets begin by understanding how does PEAR work, basically, a PEAR channel is a REST service with all the needed information about the packages on the channel, such as releases, stability, maintainers, categories and stuff. If you use this channel, the PEAR client will hit this "service" and parse all the information about the packages.

The last and final step is the installation of the package itself, the PEAR client hits the channel, parses the information about the last release of the package, download it and extract the files in the include path, nothing more, nothing less, it's that ease.

So the first step is create the channel is to set up GitHub, let's create a repository called "pear"

  1. Create the repository on GitHub
  2. $ mkdir pear
  3. $ cd  pear
  4. $ git init
  5. $ touch README
  6. $ git add README
  7. $ git commit -m 'First commit'
  8. $ git remote add origin git@github.com:[your git username]/pear.git
  9. $ git push -u origin master 

Now we must active the gh-pages branch on our new repository. In every repository, if you create a branch called gh-pages, all the files on that branch will be available on the URL http://[your git username].github.com/[you repository name], and GitHub is transformed in a webserver.

  1. $ cd pear
  2. $ git symbolic-ref HEAD refs/heads/gh-pages
  3. $ rm .git/index
  4. $ git clean -fdx

Now, the next step is create the files that compose the PEAR channel/server structure, and as you can imagine, this is a very painfull (and boring) task, but in order to make things easier, we'll use Pirum, a PEAR package that automatically create all the needed files, and since Pirum is a PEAR package, we'll install it using...PEAR.

  1. $ pear channel-discover pear.pirum-project.org
  2. $ pear install pirum/Pirum

With Pirum installed, we just need to create one more file, called pirum.xml, this file contains the basic information that Pirum need in order to create the channel structure, it must be created inside the pear folder and must be as follows:

<?xml version="1.0" encoding="UTF-8" ?>
<server>
  <name>[your github user].github.com/pear</name>
  <summary>[your github user] PEAR channel</summary>
  <alias>[your github user]</alias>
  <url>http://[your github user].github.com/pear</url>
</server>

Change the file to meet your informations and save it, and with the file created, you are ready to create the channel.

  1. $ cd pear
  2. $ pirum build . 
  3. $ git add -A
  4. $ git commit -m "Channel created"
  5. $ git push origin gh-pages

Your PEAR channel is now available (but in some cases GitHub can take up to 10 minutes to activate GitHub Pages on your acount), and you can test it out.

  1. $ pear channel-discover [your github user].github.com/pear
  2. $ pear channel-info [your github user]

Now that you have your channel, you probably want to add some packages to it, and to make this you need to create a package.xml file for each project that you want to create a package, this file can be huge, mostly by the fact that every file in your project must be listed in the package.xml file, so create the package.xml file manually can be even more painfull than the creation of the channel itself, so again, in order to make things easier, we'll use another software, Pearfarm.

Pearfarm reads all the files in your project and create the package.xml file based on a specification file. But, enough talking, let's start.

  1. $ pear channel-discover pearfarm.pearfarm.org
  2. $ pear install pearfarm.pearfarm.org/pearfarm
  3. Go to the directory that contains your project files (not the pear directory)
  4. $ pearfarm build
  5. After you run the above command, a file named pearfarm.spec will be created on the directory that contains your project files, open this file and edit the information about your project
  6. $ pearfarm build

At this point, you are ready to create your package, let's validate the package.xml file generated by Pearfarm and then build our package (at this point, you can also make manual changes on the package.xml file that Pearfarm has generated if you need, but be carefull).

  1. $ pear package-validate
  2. $ pear package 

Package created, now lets add it to your channel.

  1. Copy the .tgz file to your pear directory
  2. $ cd pear 
  3. $ pirum add . [filename].tgz 
  4. $ pirum build . 
  5. $ git add -A
  6. $ git commit -m "My first package added to my channel, thanks Gabriel Ricci"
  7. $ git push origin gh-pages

And you're done, now everyone can have access to your projects through PEAR, don't forget to take a look at my PEAR channels, http://gabrielricci.github.com/pear and http://terophp.github.com/pear and at my repositories in GitHub, http://www.github.com/gabrielricci and http://www.github.com/TeroPHP.

Oh, one last thing, in my experience PEAR is not the most easy application to deal with, it has it's own cache system which may drive you crazy, so, http://pear.php.net and Google are your friends.

quarta-feira, 23 de novembro de 2011

My essential firefox extensions

Hello, today I want to share the extensions I use in Firefox when I'm developing a website.

sexta-feira, 11 de novembro de 2011

DRY applied to web development

"Remember that feature that we've used on the other screen? We'll need to use it on this screen too, okay?"

Every developer encountered this situation or a similar one at least once , what to do to avoid this problem? Obviously this type of situation would not occur (or at least should not occur) in well-designed systems, where there is a previous survey of requirements, where there is prototyping the screens and so on, but we all know that in real life the planning does not always occur, and that even in the most well planned projects, there are always last minute changes, so how do we minimize changes? How to avoid writing code twice? How to not repeat yourself?

My answer is that as frontend programmers, developers, designers, regardless of the situation, we should always look for ways to avoid reinventing the wheel and create reusable components. This can be done in different ways, let's start with the simplest of them.

You can be a great frontend programmer, you can know javascript like the palm of your hand, but still you can delegate some of the features of your project to some framework. For example, just doesn't make sense to write a function to show or hide a element in an HTML page when you can use a framework like jQuery for this. I'm not saying you can't implement all these features if you wanted, what I mean is that it makes no sense to reimplement features that have already been implemented by other frameworks, frameworks that support all browsers in the market and will be supporting them for a long time.

The same thing happens with CSS, but in a more delicate way because typically designers who focus on CSS are usually a little bit skeptical about using CSS frameworks (such as the Blueprint), many of them think that creating a good CSS style sheet is almost artisanal, a thing that must be done by hand, like a painting, but if we have a framework that resets the browser's style to maintain a standard, if this framework provides helper classes for columns, clearfix and several other resources to expedite our work, why not use it and focus our time on the particular features of the system or site that we're working?

Thinking this way we can use the same approach even to the particular features of each system, those who have to be developed manually. For example, suppose you are working on a video management system, and you have to load a list of videos on two screens. I have seen situations in which developers write JavaScript code on both screens, and this code was pretty much the same in both screens. The code made the request to the backend, which returned a list of videos in JSON or XML, and the list was treated to be displayed in the frontend, the problem here is that we have two different codes to treat the same data structure returned by the server.

A different approach to solve the above issue would be to create a unique script for the video's management, this script would have a standard data structure that would be used on both screens, and would have methods for persistence and management of the videos:

function Video(id){

    this.id = id;
    ...attributes...

    this.save = function(successCallback, errorCallback){alert('saving');};
    this.delete = function(successCallback, errorCallback){alert('deleting');};
    this.insert = function(successCallback, errorCallback){alert('inserting');}; 
    ...business methods...
}

 
Video.getByID = function(){alert('getting by id');}
Video.getAll = function(){alert('getting all videos');}

This class would be included by the two screens and would be responsible for the management and persistence of the videos and turn them into a standard data structure for all the screens that require this feature, that way, the scripts of each screen can be focused only on how to display the elements in the screen.

DRY concepts can also be used in other areas. Besides a frontend programmer, I also work in the backend, and beyond the backend frameworks (wich help as much as the frontend frameworks), also have seen relatively simple solutions that prevent you reinvent the wheel, for example, assuming you have a single table of customers in your database and also have two or more distinct systems that can manage this table in your database, all systems have connection to this database, so if you change a column of your customer table, you'll have to update the source code on all systems that work with that column, to solve this problem we have two solutions.

Depending on the size of your database, a good approach is to use procedures for updating, inserting or deleting data, and views for displaying data, making the tables virtually transparent to the application.

Another approach is to use webservices, you create a service to manage the customer base and all applications make calls directly to this service. In this case, this service is the only one who have access to the database, and applications have access only to the service in question, this architecture is called SOA (Service Oriented Architecture).

Today, for everything you need, you almost always find ways of not having to reinvent the wheel from project to project, if you work together with a large number of developers and designers, shares CSS, javascript or any other language's code, a framework can help and can also make the collaboration between the project members easier, moreover, sometimes even a single component can become a complex component that can be used in various parts of the same project in the future, so writting reusable components is paramount today, give some thought to the future is the key to your DON'T REPEAT YOURSELF.

segunda-feira, 31 de outubro de 2011

terça-feira, 19 de julho de 2011

Função de formatação de números em php

Pequena função para formatação de números da mesma forma que em PHP.
 
var numberFormat = function(value, dec, decsep, milsep){
    // formata os parametros
    dec        = (typeof(dec) === 'undefined' ? 2 : dec);
    decsep    = (typeof(decsep) === 'undefined' ? ',' : decsep);
    milsep    = (typeof(milsep) === 'undefined' ? '.' : milsep);

    // fixa o valor
    value=value.toFixed(dec);

    // converte para string
    var localValue=value.toString();

    // separa as partes
    var arr = localValue.split('.');

    // verifica se existem casas decimais
    arr[1] = (arr.length > 1) ? (decsep + arr[1]) : '';

    // cria a expressao regular
    var re=/(\d+)(\d{3})/;
  
    // formata
    while (re.test(arr[0])){
        arr[0]=arr[0].replace(re, '$1'+milsep+'$2');
    }

    return arr[0]+arr[1];
}

terça-feira, 12 de julho de 2011

Robular - Real time regular expression tester

Robular é um editor de expressão regular baseado em Ruby, ele é útil para testar expressões regulares ao mesmo tempo que você as escreve.

Acesse em http://www.rubular.com/

terça-feira, 5 de julho de 2011

Manual de como falar bem

Prosopopéia flácida para acalentar bovinos
(Conversa mole pra boi dormir)

Colóquio sonolento para gado bovino repousar
(história pra boi dormir)

Romper a face
(Quebrar a cara)

Creditar o primata
(Pagar o mico)

Inflar o volume da bolsa escrotal
(Encher o saco)

Impulsionar a extremidade do membro inferior contra a região glútea de alguém
(Dar um pé na bunda)

Derrubar, com a extremidade do membro inferior, o suporte sustentáculo de uma das unidades de acampamento
(Chutar o pau da barraca)

Deglutir o batráquio
(Engolir o sapo)

Colocar o prolongamento caudal em meio aos membros inferiores
(Meter o rabo entre as pernas)

Derrubar com intenções mortais
(Cair matando)

Aplicar a contravenção do Sr. João, deficiente físico de um dos membros superiores
(Dar uma de João sem braço)

Sequer considerar a utilização de um longo pedaço de madeira
(Nem a pau)

Sequer considerar a possibilidade da fêmea bovina expirar fortes contrações laringo-bucais
(Nem que a vaca tussa)

Sequer considerar a utilização de instrumentos metálicos derivados do ferro
(Nem ferrando)

Derramar água pelo chão através do tombamento violento e premeditado de seu recipiente
Chutar o balde)

Retirar o filhote de eqüino da perturbação pluviométrica
(Tirar o cavalinho da chuva)

Via Zé Bisteca

Buscando texto dentro de diretório recursivamente via linha de comando

Comando muito útil caso você precise procurar por algum texto dentro de arquivos de algum diretório recursivamente, o comando que faz a mágica é o grep.

grep -R (texto) (diretorio)
E.g.: grep -R TODO .

Caso você esteja trabalhando com svn, você também pode excluir os diretórios chatos (.svn) da seguinte forma

grep -R (texto) (diretorio) | grep -v (parte do nome ou caminho do arquivo)
E.g.: grep -R TODO . | grep -v .svn

Podemos também excluir arquivos de backup de algum editor

grep -R (texto) (diretorio) | grep -v (parte do nome ou caminho do arquivo)
E.g.: grep -R TODO . | grep -v .bkp
E.g.: grep -R TODO . | grep -v .sw