Some Title Any
May 20th, 2008Verify
Technorati Profile
Verify
Technorati Profile
I really like scaffolding in grails. However I don’t like the scaffolding for the create, edit, and show. So I decided to hack up the templates. I’m not sure if there is a better way to have custom scaffolding templates. Please post if you have a good way since over riding the default might not be the best approach.
Here’s my hacked up version to use the dl, dt, and dd for create.gsp and the style sheet. The style sheet is not perfect yet but soon will be very close.
.....
<%= multiPart ? ' enctype="multipart/form-data"' : '' %>></code>
<div class="dialog"><fieldset>
<legend>Create ${className}</legend>
<%
excludedProps = [’version’,
‘id’,
Events.ONLOAD_EVENT,
Events.BEFORE_DELETE_EVENT,
Events.BEFORE_INSERT_EVENT,
Events.BEFORE_UPDATE_EVENT]
props = domainClass.properties.findAll { !excludedProps.contains(it.name) }
Collections.sort(props, comparator.constructors[0].newInstance([domainClass] as Object[]))
props.each { p ->
if(p.type != Set.class) {
cp = domainClass.constrainedProperties[p.name]
display = (cp ? cp.display : true)
if(display) { %>
<dl class=”table-display prop”> <dt class=”name”> <label for=”${p.name}”>${p.naturalName}:</label> </dt> <dd class=”value \${hasErrors(bean:${domainClass.propertyName},field:’${p.name}’,'errors’)}”> ${renderEditor(p)} </dd> </dl><% } } } %>
</fieldset>
<div class=”buttons”><span class=”button”><input class=”save” type=”submit” value=”Create” /></span></div>
</div>
….
Okay Word Press doesn’t do it justice.
fieldset {
border: 1px solid #336699;
font-family: Verdana;
font-size: 12px;
line-height: 15px;
margin: 0px 0px 5px;
padding: 0px 5px 8px;
float: left;
}
fieldset legend {
font-weight: bold;
padding: 5px;
}
.table-display dt {
float: right;
font-weight: bold;
margin: 0pt;
padding: 0.2em;
text-align: right;
width:14em;
margin-top: .3em;
}
.table-display dd {
margin: 0pt;
padding: 0.2em;
}
dl.table-display {
margin: 0.2em 0pt;
padding: 0pt;
}
dd input {
height: 100%;
}
dd select {
height: 100%;
width: 100px;
}
dd.errors {
background: #fff3f3;
border: 1px solid red;
color: #cc0000;
margin: 10px 0 5px 0;
padding: 5px 0 5px 0;
}
Have to find a plugin to display code better.
If someone wants a better copy just email me.
Hello …. I think this maybe one way of doing common domain with Grails for multiple applications. Say you have this adserver you are writing or some type of administration you need to do. Create Users , manage a bit-o-content whatever. Your site is moderately popular you get a few 10k hits or so. Why would I want my admins running on my production server sucking up the resources? I don’t so here’s what I’m doing.
I created three grails applications …. I may just cut this down to two and a groovy project later. But I like the framework making test and stuff.
I called one domain-gr , one admin-gr, and one client-gr.
Created a sym-link from the grails-app/domain from each of the domain-gr and the client-gr to the domain-gr/grails-app/domain
Created unique controller for each of my client and domain scaffolded them out changed my datasource to the same ds. BAM one domain two different apps. remember to grails -Dserver.port=9090 run-app on the second app.
Now I can host the admin app locally and the client on my prod server.
Yes …. Yes I know what about a plugin you say? Well I thought about that and I didn’t like the idea of reloading a plugin for a domain while in development. I guess I could roll the plugin later.
That’s my latest hack. Ask me about my layout div control for site-mesh sometime.
My question is anyone got a better way? Is this bad good or ugly. I like it for the DRY principle.
-Doyle
PS… Worked fine importing them into eclipse. I don’t think this will work on Windoze.
After a bit of searching for a quick and dirty on Paypal and Grails my search came up blank. After making sure I wasn’t going to reinvent the wheel. I prodded off to fine the default jsp and servlet version which I did and it was very straight forward. Some of the code below is still used from that version.
Domain Object for paypal ipn:
class Ipn {
String last_name
String address_name
String txn_type
String receiver_email
String address_city
String residence_country
String payment_gross
String payment_date
String address_zip
String payment_status
String address_street
String first_name
String payer_email
String payer_id
String verify_sign
String payment_type
String business
String address_country_code
String mc_fee
String address_status
String quantity
String notify_version
String mc_currency
String custom
String address_state
String payment_fee
String payer_status
String shipping
String item_name
String tax
String charset
String item_number
String invoice
String mc_gross
String txn_id
String receiver_id
String address_country
}
SenderController ....
def paypal = {
String amount = params.paymentOptions
String itemType
if("400.00".equals(amount)){
itemType = "Whatever Order"
}
def now = new Date()
SimpleDateFormat sdf = new SimpleDateFormat("yyyyMMddmm")
String invoice = "P"+params.userid+params.year+params.make+sdf.format(now)
String postString = "?"+"cmd=_xclick"+"&"
postString += "business=yourbuis@foo.com“+”&”
postString += “item_name=”+itemType+”&”
postString += “amount=”+params.paymentOptions+”&”
postString += “custom=”+params.custom+”&”
postString += “invoice=”+invoice+”&”
postString += “notify_url=http://foo.com/ipn” + “&”
postString += "return=http://foo.com/user/payloop/“+params.userid redirect(url:”https://www.paypal.com/cgi-bin/webscr“+postString) }
class IpnController {
def allowedMethods = [delete:'POST', save:'POST', update:'POST']
EmailerService emailerService
def index = {
def ipn = new Ipn(params)
ipn.parmscustom=params.custom
ipn.save()
Enumeration en = request.getParameterNames();
String str = "cmd=_notify-validate";
while(en.hasMoreElements()){
String paramName = (String)en.nextElement();
String paramValue = request.getParameter(paramName);
str = str + "&" + paramName + "=" + URLEncoder.encode(paramValue);
}
URL u = new URL("https://www.paypal.com/cgi-bin/webscr“);
URLConnection uc = u.openConnection();
uc.setDoOutput(true);
uc.setRequestProperty(”Content-Type”,”application/x-www-form-urlencoded”);
PrintWriter pw = new PrintWriter(uc.getOutputStream());
pw.close();
BufferedReader br = new BufferedReader(new InputStreamReader(uc.getInputStream()));
String res = br.readLine();
br.close();
def foo = MyDomainFoo.get( params.custom )
// check notification validation
if(res.equals(”VERIFIED”)) {
foo.verifiedPayment=”VALIDATED”
foo.save()
//send email
def email = [
to: [ ‘peeps@whocare.com‘ ],
subject: ‘Yadada duh’ + ipn.invoice ,
text: Information’
+ ‘nOrder Payment Status: VERIFIED’
]
// sendEmails expects a List
emailerService.sendEmails([email])
//update estimate to Validated
}
else if(res.equals(”INVALID”)) {
foo.verifiedPayment=”INVALID”
foo.save()
//send email bad here
}
else {
println(”LOG:: Something bad happened with” + ipn.custom)
}
redirect(uri:”/terminated.html”)
}
There it is in a nut-shell. It's not the cleanest but it works and works well.
What I would recommend if you are doing some paypal stuff with grails would be to do the following.
In your Config.groovy class use the following:
paypalurl = "http://localhost:8080/local-pay/foo"
analytics = "off"
environments {
test {
paypalurl = "https://www.sandbox.paypal.com/cgi-bin/webscr"
}
production {
analytics = "on"
paypalurl = "https://www.paypal.com/cgi-bin/webscr”
}
}
and use the grailsApplication.config.paypalurl convention so you can seperate the test from the production.
For Dev I used a mix of stuff with a selenium test for checking the call from paypal. below is one I use in my test calls.
?shipping=0.00&txn_id=573053526782394N&mc_fee=0.39&charset=windows-1252&address_country=United States&item_name=Stuff they bought&payment_status=Completed&address_state=FL&address_street=payer address&verify_sign=A2Aln3iC.testuffthatsunreadablegx2Elkzx&address_status=confirmed&payment_fee=0.39&payment_gross=233.99&quantity=1&first_name=payername&address_city=payercity&address_country_code=US&item_number=&mc_currency=USD&residence_country=US&payer_email=payer@foopayer.com&address_name=Brian Doyle&controller=ipn&txn_type=web_accept&payer_status=unverified&last_name=Doyle&payment_type=instant&invoice=W2008041358&payer_id=V636&receiver_id=6VX7YJ&payment_date=20:59:18 Apr 13, 2008 PDT&mc_gross=2.99&tax=0.00¬ify_version=2.4&address_zip=12345&receiver_email=paypal@foomydomaintest.com&custom=27&business=paypal@foomydomaintest.com
Also fix the business from test to production.
Need to make this a plugin....
Questions, Comments, and Improvements Accepted below...
update nice guide on how olaf descripes IPN IPN Diagram From the Dzone Dzone Link
This is just a quick post about installing MQ on Ubuntu. Since Hardy is coming out in less than a week I’ll need to do it again.
Install rpm
*Your mount steps may vary.
mkdir tmp-mq
sudo mount -t iso9660 -r -o loop /media/FIRELITE/ISO/WMQ_600.iso ~/tmp-mq/
./mqlicense.sh
rpm -ivh –nodeps MQSeriesRuntime-6.0.0-0.i386.rpm
rpm -ivh –nodeps MQSeriesServer-6.0.0-0.i386.rpm
rpm -ivh –nodeps MQSeriesJava-6.0.0-0.i386.rpm
rpm -ivh –nodeps MQSeriesSamples-6.0.0-0.i386.rpm
rpm -ivh –nodeps MQSeriesMan-6.0.0-0.i386.rpm
rpm -ivh –nodeps MQSeriesIES30-6.0.0-0.i386.rpm
rpm -ivh –nodeps MQSeriesConfig-6.0.0-0.i386.rpm
Rinse and repeat the steps above for the patches from IBM.
su - mqm from root
Create a Queue Manager :
crtmqm TEST
Configure:
strmqcfg -c
Add your self to the MQM Group.
You should be good to go.
Launching the MQ Explorer.
create a workspace in your home mine is called mq-ws
/opt/mqm/ies30/eclipse/.eclipse
Use the workspace you created in the above step.
You should be golden now. Much props to Nacho M. for the rpm stuff.
-Doyle
I suggested that we start doing weekly code reviews on two projects that I’m currently developing on. So we are on week three of one and week one of another. This is a break from the norm where we normally do the code reviews when we are done coding. I’ve been screaming for incremental code reviews for along time.
Some Do’s:
Benefits:
That’s about it for right now. We have caught some holes in the design that would not have been caught until test. I think anyone can apply ICR to whatever methodology the subscribe to e.g. waterfall , agile … etc. We also seem to have a more complete earlier?
I guess I should add that one team has four and the other has three.
Don’t do the review if you don’t have the business people involved.
Today I was doing some refactoring in RAD (Rational Application Developer) and found my self looking over in the package explorer thinking gee I’ll have to move that method over to the class I just created to get rid of the two classes I’m factoring out. I looked over and thought I should be able to just drag it down into the other class. BAM like a champ when I grabbed that green orb it moved right over when I plopped it down on the new class, updated all the reference just like I would have done it via ALT+SHIFT+V and navigate around to the class I wanted it to go. Normally I’m a keyboard Jedi but I guess I’ll be making an exception.
Finally added the hook from my home page to my blog. This should be much better now. Have to fix the special characters … things to do things to do.
What’s the deal with tying a napkin around the coffee pot handle? What does this mean? Does it mean that the coffee is no good, are you cleaning the pot, is it god forbid decaf (I use the orange pot for regular coffee if I have to make it). Seriously, I need to know what this mean! All I know is that every time I see that pot with that napkin it smells like starbucks. I hope you don’t mind that I poor it into the orange pot and brew the marked coffee with regular coffee.
You know you could just get some tape and tell me what is in the pot. Just in case it’s not the star-crack.
Can we talk about the lack of donuts ….