The grails release plugin is great for publishing plugins to grails central but it will also publish a plugin to a maven repo. You simple need to configure the new maven repo inside build config. But if you want to release snapshots to an internal maven but not have that config checked in publicly that is a bit more tricky. With a quick bit of code added to BuildConfig.groovy we can have it pull in the config from a file we can choose to not checkin. Now with our public code we don’t need to expose our internal login info. See the file changes below for an example.

Add this to BuildConfig.groovy:

1
2
3
4
5
6
7
8
9
10
11
def mavenConfigFile = new File("${basedir}/grails-app/conf/mavenInfo.groovy")
if (mavenConfigFile.exists()) {
  def slurpedMavenInfo = new ConfigSlurper().parse(mavenConfigFile.toURL())
  slurpedMavenInfo.grails.project.repos.each {k, v ->
      println "Adding maven info for repo $k"
      grails.project.repos."$k" = v
  }
}
else {
  println "No mavenInfo file found."
}

Then you can create a file called mavenInfo.groovy:

1
2
3
grails.project.repos.internalSnap.url = 'http://internal.com:8080/nexus/content/repositories/internal-snapshots/'
grails.project.repos.internalSnap.username = 'fakeUser'
grails.project.repos.internalSnap.password = 'fakePass123'

Grab the gist.

I am using a simple redirect after a user logs in so they can get to the page they were heading too the URLs were ending up with %2F in the url which caused a 404 error. The problem wasn’t actually in Grails at all but in the mod_rewrite rule being used to force HTTPS connection the rule was set up to end with [L,R] when to correctly deal with the url encoding we were already doing it needed to be [NE,L,R]

Reference: http://www.webmasterworld.com/apache/3279075.htm

When working with jQuery 1.6.1 and the jQuery Form Example Plugin I found that the examples were being serialized the plan was to use Ajax to send the serialized data back to the server and save it but I didn’t want to have to try and remove the examples server side. So triggering unload on the examples will allow serialize to get the correct data. Example JavaScript below.

1
2
3
4
var examples = $('.example');
_.each(examples,function(elm){
    $(elm).unload();
});

I used Userscore.js to give me a quick foreach style loop and called the unload event on every element that has the class .example which is the default class that jQuery Form Example plugin uses.

So dealing with Datetime between client and server side can always be fun due to timezones but adding a number of browsers makes it all the more complicated. For our project we are using Joda-Time on the Java side and a mix of technologies on the client side (I will be addressing that soon). So we deiced to pass all datetimes via ISO-8601 the problem came when dealing with the different browsers. IE7 and IE8 both output a string that doesn’t have the milliseconds where Chrome and FireFox did.

On the Java side we used ISODateTimeFormat.dateTime() to parse the incoming date string so we wanted the milliseconds.

To make this work I made a quick JavaScript utility that I can use to output the correct format in UTC time as we wanted. You can see the code below.

As we know how to hide the address bar in iOS, we may want to tell if a user has that bar showing or not. I use this detection to show instructions to the user to add a site to their home screen if they are not in stand alone mode.

There are two properties we want to look at “standalone” in window.navigator and window.navigator.standalone. We can use the first expression to check if the device supports full screen mode and the second to check if it is in full screen mode. I have checked these with the iPhone and iPad, with iOS versions 3 and 4 if anyone has any issues please post a comment and we can try and work through it.

The following checks will after the page is loaded output to the console the mode its in. From there you can easily replace the console.log with what ever functions you would like.

There is a great write up by Ben Nadel you can find over at his blog. Post

If you are creating a web app for the iPhone there is an easy to to hide the address bar when opening the page from a link on the users home screen. You simply need to add the following meta tag to your
head. This will also work with the iPad.

1
<meta name="apple-mobile-web-app-capable" content="yes" />

The Problem

The iPad and also the iPhone have a bit of special behavior when it comes to using the HTML5 video tag. They both have the autoplay functionality shut off. This behavior is also extended to any event which the user has not started the event chain. (AKA you can’t do the following)

1
<body onLoad="document.myMovie.play()">

What it Means

So what this really means you can not have a playlist of videos where one video is loaded as soon as the first ends. Also having timed events from one video kick off sub videos will not work unless the user clicks on the new video.

Is this a Bug?

No this is as intended by Apple look for the Device-Specific Considerations here. What the idea is that any device that could be charged from a data plan shouldn’t allow auto play. While this idea makes sense the execution is poor. I am currently using a wifi only iPad so there is no reason for this restriction it would be best in my mind to detect if they are using wifi or 3g and react accordingly.

What to Do

Design around this I restructured an interaction from popping up this sub video over the main video to instead make a thumbnail active so it could be click to show this sub video this works in my case as the sub video can be viewed any time after the timed event.

Another option is to show the new video element that will display a play symbol you should be able to set a poster image with some text to guide the users.

I have been working with the HTML5 video element a bit on both iPad and the Chrome browser. I’ve started to find some odd behavior around the seeked event. First a touch of background about the seeked event. According to the spec the seeked event should fire when the seeking IDL attribute changes to false. This seems to make perfect sense but when actually using the event it seems inconsistent at best.

I have seen three distinct actions that don’t make sense to me.

Extra Fires

  • While dragging the scrub bar the seeked event will fire many times in the Google Chrome 5.0.342.9 beta on windows.
  • When setting the position by changing the currentTime attribute it will fire the seeked event three times in a row on both the iPad and Chrome.

No Fires

  • Scrubbing on the iPad never fires the seeked event.

So from what I can tell its not the best idea to use the seeked event at this point but the timeupdate event does fire consistently through my testing. So what you can do if you like is keep track of a last value for the timeupdate and then you can detect if it jumps too far (up to you and your use) then fire the logic you wanted to fire on seeked. I am kicking off events at times and I didn’t want to miss events so simply changing my logic to fire as long as the time is past the event point worked fine for my uses but that may not always work. Keeping track of the last time from the timeupdate shouldn’t be a very hard addition if you need special seek logic.

While working on a small HTML5 based project for the iPad I found some interesting things with how it handles the poster attribute and defining the video source. The following HTML works fine on Mobile Safari (iPad) and my desktop Chrome.

1
2
  <video id="vidtest" src="big_buck_bunny.mp4"  poster='poster.jpg' controls="controls">
  </video>

But moving to the following code works fine in Chrome but on the iPad (Mobile Safari) it will only show the poster and no way to start the video unless you do the pinch zoom to make the video full screen then the controls will show up.

1
2
3
   <video id="vidtest"  poster='poster.jpg' controls="controls" >
      <source src="big_buck_bunny.mp4" type="video/mp4" />
   </video>

Simply using the first style is ok if you are only doing one type of video but if you wanted to include other options this issue limits that ability. But for now if you are targeting iPad just use the first option.

One feature I have really liked on my blogs recently is the ability to just use Twitter to comment so I went ahead and added the DISQUS Comment system the plugin is straight forward and easy to use with WordPress. Moving forward with new site projects I will be strongly considering using DISQUS instead of an internal comment system, I would suggest checking it out as well as InenseDebate .