Muito bom esta tabela que mostra o que cada cliente de email consegue mostrar corretamente em termos de CSS nos emails Html que vc envia.
http://www.campaignmonitor.com/css/
Ou seja, não adianta referenciar um arquivo CSS na tag link lá no header, pois nem todos os clientes levam isso em consideração. E nem tag style no header, e nem..... olhe o link acima.
Abcs
Felipe
14 de outubro de 2009
29 de setembro de 2009
Serviços do Grails, Transações e Rollback automático
Comprei o livro recente que saiu do Glen Smith, o Grails in Action. E, claro, comecei a ler. Ainda não terminei. Mas já valeu a compra e a dedicação de ler só pelo fato que eu descobri e não sabia:
Nos serviços do grails ( classes *Service.groovy, dentro do diretório services), que possuem Transação Declarativa , o default é cada método ser transacional. Isso significa que uma transação será iniciada antes do método do serviço começar a ser executado, e será finalizada (commit ou rollback) ao final.
O rollback acontece automaticamente quando uma Exception é lançada. O que eu não sabia era que apenas Runtime Exceptions fazem o rollback acontecer. Checked Exceptions não. Isso mudou minha vida! :-)
Eu fazia um try catch no controller, às vezes, pegando o tipo Exception no catch. Grave erro conceitual de cara né, mas pior ainda, pois eu estava contando com o rollback que poderia não acontecer.
Então amigos: apenas classes derivadas de RuntimeException fazem o rollback acontecer.
Abcs
Manubia.com.br - Controle Financeiro com Grails e, agora, com jQuery
É pessoal....
depois de algum tempo, tempão mesmo, usando a dupla Prototype + Scriptaculous.....depois de saber usar bem esta dupla, de ler livro e tudo..... resolvi abandonar totalmente a dupla e me render ao jQuery.
Deu um trabalho danado migrar o Manubia.com.br (site de controle financeiro) para o jQuery. Tem muita coisinha diferente. Mas no final das contas, estou gostando muito.
Alguns dos motivos de ter feito a migração:
- jQuery tem um mundo plugins que resolvem diversos problemas que a gente precisa ficar catando pela web quando usamos Prototype + Scriptaculous.
- o jQuery tem um projeto inteiro dedicado a interface gráfica: jQuery UI
- formatação de campos de um formulário (formatar valor numérico com pontos e vírgulas, de forma internacionalizada): Masked Input Plugin
- Calendário tipo Date Picker para campos de datas: jQuery UI DatePicker
- Plugin para manipulação de comboboxes (select boxes).
- No final das contas, a gente escreve menos código JavaScript do que com Prototype. Parece que fica mais limpo o código.
- Tem um site dedicado aos plugins
- De acordo com alguns benchmarks (um aqui, outro aqui), o jQuery tem uma performance melhor do que o Prototype (ou seja, os usuários é que ganham).
- Eu tenho tudo que preciso em uma biblioteca só, não preciso usar parte de uma, parte de outra, etc... (pelo menos por enquanto, vamos ver até quando).
É isso. Acho que o Manubia ganhou com este investimento que fiz... No fundo mesmo, eu precisava era do formatador numérico para campos input. Aí achei o plugin de jQuery...isso foi a gota d'água pra eu migrar. (Eu já tava p da vida por estar usando o date picker do Open Rico)
Abcs
Felipe
9 de setembro de 2009
Filtro do Grails para impor SSL (https) a determinadas páginas
Olá pessoal,
hoje andei pesquisando a respeito de uso de certificados SSL com uma aplicação grails. Afinal, está chegando a hora de impor o uso de SSL (https) meu novo site de controle financeiro, o Manubia.com.br .
Então ao pesquisar o assunto, encontrei uma classe de um grails Filter que pode me ajudar muito em forçar determinadas URLs a usarem SSL e outras não. Por exemplo, uma página que mostra dados não confidenciais, não precisa usar SSL (https). Já uma página que mostra ou recebe um formulário confidencial DEVE usar SSL.
Aí vai o Filter. Ainda não testei, mas parece certinho.
Abcs
/**
* Created by IntelliJ IDEA.
* User: danielhonig
* Date: Jan 23, 2009
* Time: 4:27:10 PM
* To change this template use File | Settings | File Templates.
*/
import org.codehaus.groovy.grails.commons.ConfigurationHolder
class SSLFilters {
// Set these to your HTTP/HTTPS ports
def defaultPortHTTP = 80
def defaultPortHTTPS = 443
static def SSLRequiredMap = ConfigurationHolder.config.SSLRequiredMap
def shouldUseSSL(controllerName, actionName) {
// User actions use SSL
if (SSLRequiredMap[controllerName]!=null) {
//If * then all actions are secured
if (SSLRequiredMap[controllerName][0] == '*')
return true
//else look for specific action
if (SSLRequiredMap[controllerName].contains(actionName))
return true
}
false
}
def filters = {
sslFilter(controller: "*", action: "*"){
before = {
def controller = controllerName
def action = actionName
log.debug("SSLFilter: ${params?.controller}.${params?.action}")
def url = null
// SSL off by default
def useSSL = shouldUseSSL(controllerName,actionName)
log.debug("${controller}.${action}, useSSL:$useSSL")
// Get redirected url
url = getRedirectURL(request, params, useSSL);
// If redirect url returned, redirect to it
if (url) {
redirect(url: url)
return false;
}
return true;
}
}
}
def getRedirectURL = {request, params, ssl ->
log.debug("getRedirectURL: $ssl")
// Are we there already?
if (request.isSecure() == ssl)
return null;
def protocol
def port
// Otherwise we need to flip
if (ssl) {
protocol = 'https'
// If using the standard ports, don't include them on the URL
port = defaultPortHTTPS
if (port == "443")
port = ""
else
port = ":${port}"
}
else {
protocol = 'http'
// If using the standard ports, don't include them on the URL
port = defaultPortHTTP
if (port == "80")
port = ""
else
port = ":${port}"
}
log.debug("Flip protocol to $protocol")
def url = request.forwardURI
def server = request.serverName
def args = paramsAsUrl(params)
url = "$protocol://$server$port$url$args"
log.debug("getRedirectURL - redirect to $url")
return url;
}
def paramsAsUrl = {params ->
int ii = 0
String args = ""
params.each
{k, v ->
if (['controller', 'action', 'id'].find {k == it})
return;
if (ii)
args += "&"
else
args += "?"
args += "$k=$v"
ii++
}
return args
}
}
6 de setembro de 2009
Controle Financeiro e Planejamento Financeiro com Grails e Prototype
Mês passado eu e um grande amigo, e meu sócio neste projeto, lançamos um site para controle financeiro pessoal: www.manubia.com.br
O site foi todo desenvolvido com Grails e a dupla Prototype/Scriptaculous.
Tenho me questionado se não deveria mudar para jQuery. Eu vi um benchmark e acabo ficando na dúvida. Alguém prefere o jQuery ao invés do Prototype?
Em fim..... o sistema do Manubia foi ótimo de ser feito com o Grails. É incrível a produtividade do Grails, todos os plugins (estou usando authentication plugin, mail plugin e o mail-confirmation plugin). E bastante efeito visual e ajax com o Prototype e o Scriptaculous. Tá ficando legal.
Sobre o sistema em si, é um sistema de controle financeiro, onde você pode inserir suas transações, ou importar arquivo do seu banco, e em seguida pode categorizar todos os seus gastos. Feito isso, o sistema apresenta gráficos muito interessantes comparando seus gastos ao longo dos meses, resumo de suas contas , entre outros. É muito interessante pois assim você tem visibilidade dos seus gastos, e pode, portanto, fazer um planejamento financeiro para a sua família.
Eu importei meus dados dos últimos 4 meses, e foi ótimo pois consegui, junto com minha esposa, descobrir nossos ralos financeiros. Assim poderemos fechar esses ralos e poupar um pouco mais...
Abcs
Felipe
28 de julho de 2009
Instalador para Mac de uma aplicação Java
Excelente artigo de como criar um installer para Mac de uma aplicação Java. Como esse artigo me salvou legal, copio ele aqui, só pra não perder.
Original em: http://www.centerkey.com/mac/java/
How to Create a Mac OS X Installer for a Java Application
(Updated for Mac OS X 10.5 — Leopard)
With some simple steps you can turn your Java Swing program (.jar) into a proper Mac OS X application with a native installer. The instructions below step you through the process from scratch with a sample program called
SCREENSHOT
ICONS
↓
"It's Showtime!" which simply displays the current time. Once you have successfully completed the tutorial with the sample Java program, modify the steps to work for your Java program.ICONS
↓
1) Install Xcode
Before continuing to the next step, it's a good idea to perform a "Software Update..." to make sure your OS files are current.
2) Launch Unix Terminal
3) Make Project Folder
mkdir ItsShowtime
cd ItsShowtime
The first command creates a folder called "ItsShowtime", and the second command moves you into the new folder.cd ItsShowtime
4) Write Some Java Code
pico ShowTime.java
Enter the following code:ShowTime.java
import java.util.Calendar; import javax.swing.*; public class ShowTime { public static void main(String[] args) { JFrame f = new JFrame(); f.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); f.setTitle("It's Showtime!"); f.getContentPane().add(new JLabel( Calendar.getInstance().getTime().toString())); f.pack(); f.setVisible(true); } }Use
5) Compile Java Program
javac ShowTime.java
ls -la
We could run the class file directly, but a class file is cumbersome. Instead we will create an executable JAR file.ls -la
6) Make Executable JAR
pico MainClass.txt
Our manifest file will only have one line:MainClass.txt
Main-Class: ShowTimeExit Pico and use the following "jar" command to create the "ShowTime.jar" file:
jar cmf MainClass.txt ShowTime.jar *.class
ls -la
Now test your executable JAR with the following command:ls -la
java -jar ShowTime.jar
The "It's Showtime!" window with the current time should display in the upper left corner of the screen. Click the red dot to exit the program.While the manual commands for steps #5 and #6 above work fine, you can automate them using Ant with this build.xml file.
7) Create Application Icon
Download and save (
Then move the file into the "ItsShowtime" folder with the following command:
mv ../Desktop/ShowTime.png .
Now we can create the icon file.Steps:
- Use "Finder" to navigate into the "Developer:Applications:Utilities" folder and double-click "Icon Composer".
- Go back to "Finder" and navigate to your "ItsShowtime" folder (which is in your home folder).
- Drag the "ShowTime.png" image file into the "128" box on the "Icon Composer" screen. When prompted about sizes, choose "Copy to all smaller sizes" and then click the "Import" button.
- Go into the "File" menu and select the "Save" option. Then deselect the "Hide extension" option and save as "ShowTime.icns".
- Quit "IconComposer".
8) Bundle the JAR
Steps:
- For the "Main Class:", use the "Choose..." button and go to and choose "ShowTime.jar".
- Check the "Use Macintosh Menu Bar" option.
- Use the "Choose Icon..." button to choose the "SnapBackup.icns" file (you'll need to navigate to the very top-level folder and then into the "Users" folder and your home folder to eventually find the "ItsShowtime" folder).
- Click the "Properties" tab and enter "1.0" into the "Version:" field.
- Also enter "1.0" into the "Get-Info String:" filed.
- Click the "Create Application..." button.
- Navigate into the "ItsShowtime" folder.
- In the "File:" field, enter "Show Time".
- Click the "Create" button.
- Quit "Jar Bundler".
9) Create Mac Installer
Steps:
- In the "Organization:" field on the "Install Properties" window, enter "com.centerkey". Then click "OK".
- In the "Title:" field enter "Show Time".
- Go to the "Project" menu and select "Add Contents...". Navigate to "ItsShowtime" folder and select "Show Time".
- Click on the "Contents" tab. Check the "Include root in package" option and click the "Apply Recommendations" button.
- Now click the "Build" (hammer) button. In the "Save As:" field, enter "ShowTimeInstaller.pkg". Click the "Save" button and then the "Return" button.
- Go to the "File" menu and select "Save". In the "Save As:" field, enter "ShowTime.pmdoc" and then click "Save".
- Quit "PackageMaker".
10) Put Installer on a Web Page
29 de junho de 2009
Logging com Grails 1.1
Hoje fiquei tentando entender a configuração do Logging no grails 1.1...pois mudou um pouco.
Tem um bom exemplo aqui, que eu reproduzo abaixo.
Tem um bom exemplo aqui, que eu reproduzo abaixo.
log4j = {
appenders {
console name:'console', threshold:Level.ERROR,
layout:pattern(conversionPattern: '%p %d{ISO8601} %c{4} %m%n')
rollingFile name:"rollingFileTrace", threshold:Level।TRACE, maxFileSize:1048576,
file:logFile+'Trace।log', layout:pattern(conversionPattern: '%p %d{ISO8601} %c{5} %m%n')
rollingFile name:"rollingFileDebug", threshold:Level।DEBUG, maxFileSize:1048576,
file:logFile+'Debug.log', layout:pattern(conversionPattern: '%p %d{ISO8601} %c{5} %m%n')
rollingFile name:"rollingFileError", threshold:Level.ERROR, maxFileSize:1048576,
file:logFile+'Error.log', layout:pattern(conversionPattern: '%p %d{ISO8601} %c{5} %m%n')
}
error console, rollingFileDebug, rollingFileError, rollingFileTrace:
'org.codehaus.groovy.grails.web.servlet', // controllers
'org.codehaus.groovy.grails.web.pages', // GSP
'org.codehaus.groovy.grails.web.sitemesh', // layouts
'org.codehaus.groovy.grails."web.mapping.filter', // URL mapping
'org.codehaus.groovy.grails."web.mapping', // URL mapping
'org.codehaus.groovy.grails.commons', // core / classloading
'org.codehaus.groovy.grails.plugins', // plugins
'org.codehaus.groovy.grails.orm.hibernate', // hibernate integration
'org.springframework'
debug rollingFileDebug, rollingFileTrace:'org.hibernate',
'com.britetab',
'BootStrap',
'org.apache.ddlutils'
trace rollingFileTrace:'org.hibernate.SQL',
'org.hibernate.type',
'flex.messaging.services'
warn console,rollingFileDebug,rollingFileTrace:'org.mortbay.log',
'org.hibernate.tool.hbm2ddl'
root {
trace 'rollingFileTrace'
debug 'rollingFileDebug','rollingFileTrace'
error 'console','rollingFileError','rollingFileDebug','rollingFileTrace'
additivity = true
}
}
Assinar:
Postagens (Atom)
