Monday, December 14, 2009

Working With HTML's Underrated UL and LI Tags

I think it is important to note that the HTML tag ul is short for unordered list. Many novice html coders think ul and li (and indeed ol) tags are for bullet points, but the main purpose of these tags is to define lists. A list can run verticaly, or horizontally, and elements can be separated by any manner of means - the default rendering of a list just happens to be that of a series of bullet points.

Tutorials illustrating how to use css to turn a list into a top navigation bar for a website abound on the web, so I'm no need to go there. Instead, I'm going to illustrate how to use the ul and li tags to get a nice bottom navigation, that would typically include a privacy policy, and a copyright declaration.

First lets define the list of elements to go in our bottom navigation in HTML:




Now that we have defined the content in a structured way, we have to turn our attentions to the style.


#footer-nav li{float:left;list-style:none;}
#footer-nav li:before{content:"\2014\a0";}


The above css removes the default list style of the HTML elements, and instead adds a dash before each element. Combining the style, and the data structure, we get the following list:



Now we have our navigation list running horizontally, separated by dashes, and all that is needed is for us to tidy it up a little bit. In doing that our HTML became:




And our CSS became:

#footer-nav li{float:left;list-style:none;font-size:10pt;color:#fff;}
#footer-nav li:before{content:"\2014\a0";color:#fff;margin-left:2px;}
#footer-nav li.first:before{ content:"";margin-left:0px;}
#footer-nav a:link, #footer-nav a:hover, #footer-nav a:visited{color:#fff;text-decoration:none;}
#footer {float:left;padding:10px;background-color:#039;}


And our menu became:

Wednesday, December 9, 2009

Using Groovy Scripting To Remove Unwanted MySQL Databases

Doing some Autumn cleaning on a server, I wanted to delete a lot of redundant mysql databases. There were over 900 databases, of which about 90% could be deleted or archived.

To create a list of databases from a terminal window first create a file show_db.sql
:

echo "show databases" > show_db.sql

Then use this file to generate a text file containing a list of your databases

mysql -p < show_db.sql > dblist.txt

The resulting text file had unwanted characters and spaces. Fortunately file manipulation is easy in groovy.

def file = '/tmp/dblistOriginal.txt'
def targetFile = new File('/tmp/dblistClean.txt')
if (targetFile.exists()) targetFile.write("")
new File(file).text.eachLine { line ->
targetFile.append( line.replace('|', '').trim() )
}

I reasoned it was better to keep the archieve and deletion tasks separate incase something went wrong in the process. So, firstly I created an archieve script to dump all the databases, and tar them into one file.

def dbsToPreserve = new File('/tmp/dbsToSave.txt') // list of databases to exclude
def dbsList = new File('/tmp/dblistClean.txt')
def archiveScript = new File('/tmp/archiveAndDeleteDBs.sh')
def password = 'pwd12345'
def scriptBackupFolder = 'archived_dbs'

dbsToPreserveList = []
dbsToPreserve.text.eachLine { line ->
dbsToPreserveList << line.trim()
}

// Archive Script
if (archiveScript.exists()) archiveScript.write("")
archiveScript.append('#!/bin/sh \n')
dbsList.eachLine { line ->
if(!dbsToPreserveList.contains(line)){
def dbName = line.trim()
archiveScript.append("mysqldump -p$password $dbName > /tmp/$scriptBackupFolder/${dbName}.sql \n")
}
}
archiveScript.append('cd /tmp \n')
archiveScript.append("tar -czf dbArchives${(new Date()).getTime()}.tgz $scriptBackupFolder \n")


Next, I created the sql to delete all the relevant databases


// SQL Script
if (sqlScript.exists()) sqlScript.write("")
dbsList.eachLine { line ->
if(!dbsToPreserveList.contains(line) && !line.contains('-')){
def dbName = line.trim()
sqlScript.append("DROP DATABASE IF EXISTS $dbName;\n")
}
}


Using my newly created files, has saved me so much time, and kept me from doing oh so tedious work. Thanks again Groovy!

Tuesday, December 8, 2009

Overriding Domain Class Getters and Setters in Grails

One might assume that it is possible to override getters and setters in the following manner:


def setName(String name){
//do stuff
}
def getName(){
//do stuff
return name
}


but infact static typing is required

public void setName(String name){
//do stuff
}

public String getName(){
//do stuff
return name
}

Saturday, December 5, 2009

My Data Nest Registration Error

mydatanest can't handle us Irish, or at least our names.
This error appeared to me, on my first attempt at registration:

MySQL Error: You have an error in your SQL syntax;
check the manual that corresponds to your MySQL server version
for the right syntax to use near 'Connell',`address`='Dublin',`refferal_id`=NULL,`phone`='',
`max_messages`='20000'' at line 1 on line 244
in /home/datan3st/public_html/account.php

Friday, December 4, 2009

Grails doesn't handle gstrings in controllers

You would expect Groovy gstrings and plain strings to be interchangable in Grails, but today I discovered that it is not so. In a Grails controller calling the redirect operation like this works:

redirect(action:'step1') // redirects to step1

but like this does not, and it redirects to the default index action

redirect(action:"step${getNextStep()}") //redirects to next step if it worked

the temporary solution to achieve dynamic actions is to convert the gstring into a string like so:

redirect(action:"step${getNextStep()}".toString())

Thursday, December 3, 2009

Kris Kindle / Secret Santa the Groovy Way

In efforts to explain to folks in the office how secret santa works I directed them to take a look at this secret santa definition or alternatively to examine the following groovy code:


def ezbPeeps = User.findByCompanyName('eazybusiness')
def hatOfNames = ezbPeeps.collect{it.name}
ezbPeeps.each { peep ->

def goodPick = null
while(!goodPick){
def randomInteger = RandomInteger.getGenerate()
assert randomInteger > 0
def index = randomInteger%hatOfNames.size()
switch( hatOfNames[index] ){
case peep.name:
goodPick = false
break
default:
goodPick = true
print "${peep.name} gets ${hatOfNames[index]}"
hatOfNames.remove(index)
break
}
}
}

mistakes on a postcard to Eamonn O'Connell, Saasplex, 3015 Lake View
Drive, Citywest, Dublin, Ireland

Ubuntu adds did you mean to command line

Just miss spell a command in the the terminal window to see what I mean.

I mistyped pico as pioc and recieved the following response:


pioc
No command 'pioc' found, did you mean:
Command 'pico' from package 'nano' (main)
Command 'pico' from package 'alpine-pico' (universe)
Command 'pic' from package 'groff-base' (main)
pioc: command not found


This appears to be one of the added benefits of the Karmic release. Pretty cool!