Blog Feed - Steve McKeogh All blog articles from SteveMcKeogh.co.uk http://www.stevemckeogh.co.uk/feeds/blog/ 2010-02-19T18:41:24Z Steve McKeogh http://www.creativecommons.org/licenses/by-nc/2.5/rdf Installing Railo with Apache on Windows Server http://www.stevemckeogh.co.uk/blog/2010/2/installing-railo-with-apache-on-windows-server/ 2010-02-19T18:41:24Z 2010-02-19T18:44:24Z <p>Recently I had to build a ColdFusion site on a server that didn't have ColdFusion, and what with it's hefty price tag, the admin team weren't in no rush to get a ColdFusion license. So this is when we come up with <a href="http://www.getrailo.org/" target="_blank" title="This link opens in a new window">Railo</a>, an open source alternative to ColdFusion... and I gotta say, in many ways it surpasses ColdFusion!</p> <p>However, the first issue I came upon was when I tried to install it alongside Apache on my Windows Server 2003 box, the documentation on the Railo site fell slightly short in detailing this. So I had to do some digging myself and finally got it up and running, here is a step-by-step guide for you.</p> <ol> <li>Firstly, install <a href="http://httpd.apache.org/" title="This link opens in a new window">Apache</a> and make all the changes you normally would with your Apache install. I'm not going to detail how to install Apache as it's very simple to do.</li> <li>Now you want to download Railo. Head on over to the <a href="http://www.getrailo.org/index.cfm/download/" target="_blank" title="This link opens in a new window">Railo download</a> page and you want to download the <strong>Railo Server</strong> for Windows .exe file (e.g. railo-3.1.2.001-resin-3.1.9-with-jre-windows.exe).</li> <li>Stop the Apache server if you have it running, just to make sure that Railo doesn't hit any snags whilst installing. Now run the Railo setup .exe you just downloaded and install it to your server (e.g. D:\railo\). Also take note that Railo should not be installed in a directory containing a space (e.g. C:\Program Files\) in the path name. This is a known issue in the version 3.1.9 of Caucho Resin.</li> <li>Once Railo has been successfully installed, you should see <strong>Railo x.x Server</strong> in your services listing on Windows Server. If the Railo server is currently running, stop it, as we need to now tell Apache about Railo before we can get it working.</li> <li>Open up your Apache config file (e.g. D:\Apache2\conf\httpd.conf) and scroll down to the end of the <code>LoadModule</code> block. Under the last <code>LoadModule</code> add the following</li> </ol> <pre><code>LoadModule caucho_module D:/Railo/win32/apache-2.2/mod_caucho.dll</code></pre> <blockquote>Take note that the path above must lead to your Railo directory path.</blockquote> <ol start="6"> <li>Now you want to edit the <code>VirtualHost</code> of the site that you want to run Railo, so go to the <code>VirtualHost</code> block containing your site (there are several places you could have put this) and add the following (marked in green)</li> </ol> <pre><code>&lt;VirtualHost *:80&gt; ServerName sitename.local DocumentRoot E:/path/to/site <span style="color:green">ResinConfigServer localhost 6800 &lt;Location /caucho-status&gt; SetHandler caucho-status &lt;/Location&gt;</span> &lt;/VirtualHost&gt;</code></pre> <blockquote>The above tells Apache that we want to use Resin and Railo (defaulted to port 6800) for this site.</blockquote> <ol start="7"> <li>That's Apache dealt with, now we need to add a small bit of config to the Resin config file to tell it about the site. So open up your resin.conf file (e.g. D:\railo\conf\resin.conf) and do a find for <code>&lt;cluster id="app-tier"&gt;</code>. Now find it's matching end tag <code>&lt;/cluster&gt;</code> and add the below just <strong>before</strong> this end tag (so it's inside the <code>&lt;cluster id="app-tier"&gt;&lt;/cluster&gt;</code>)</li> </ol> <pre><code>&lt;host id="sitename.local"&gt; &lt;web-app id="/" root-directory="E:/path/to/site"/&gt; &lt;/host&gt;</code></pre> <blockquote>The above <code>root-directory</code> must match your Apache <code>VitualHost</code> <code>DocumentRoot</code>. It's also worth pointing out that Railo will not see any Application.cfc above this root folder, so you will have to move your Application.cfc in to the top level folder (in this case the E:/path/to/site folder).</blockquote> <ol start="8"> <li>That is all the config done, Railo and Apache should now talk to each other and your site should run .cfm pages.<br /><br />However, there is one thing I need to point out, leave a few seconds between starting your Railo server and Apache, otherwise you will get Service Unavailable message that won't go away. So start your Railo server, then wait a minute or so and start your Apache server. Open up a browser and go to your Railo website, on initial load you will likely see a 404 page not found message, hit refresh and you will see a Service Unavailable message, then hit refresh again and you should see your site. Strange I know, but as long as it works, who cares, cos you won't see that again.</li> <li>Now that you have Railo setup, you will likely want to manage the server (just like the ColdFusion administrator), well Railo has a slight difference here, it has an admin page for every app, and a admin page for the entire server, pretty neat huh? The two URL's of these administrators are similar to the below:</li> </ol> <pre><code><strong>Server</strong>: http://sitename.local/railo-context/admin/server.cfm <strong>Web:</strong> http://sitename.local/railo-context/admin/web.cfm</code></pre> <p>If you are receiving a lovely 403 error message on your site, then chances are this is because Apache is refusing access to some files. To overcome this, add the following to your <code>VirtualHost</code> block:</p> <pre><code>&lt;Directory E:/path/to/site&gt; Options +FollowSymLinks AllowOverride all Order allow,deny Allow from all &lt;/Directory&gt;</code></pre> <p>Don't forget to follow step 8 above again after making this change.</p> Delete a record from a ColdFusion query http://www.stevemckeogh.co.uk/blog/2010/1/delete-a-record-from-a-coldfusion-query/ 2010-01-13T17:18:56Z 2010-02-16T23:20:56Z <p>Firstly, I found this method out from <a href="http://www.bennadel.com/blog/204-Using-ColdFusion-Query-s-Underlying-Java-Methods-For-Query-Manipulation-And-Logic.htm" target="_blank" title="This link opens in a new window">Ben Nadel</a>, and it is a very useful method as well.</p> <p>Ever since I can remember, if I wanted to delete a record from a ColdFusion query (<code>queryNew()</code>) I would have to go around the houses. For example, I would loop and rebuild the query, whilst omitting the row I want to delete, not ideal!</p> <p>Well with this new found function (part of the Java object it sits on), as long as you have the row index you can remove it very easily. For example, if I know that row 4, in my 10 row ColdFusion query is the one I wish to remove, I would do the below:</p> <pre><code>&lt;cfset local.query.RemoveRows(4,1) /&gt;</code></pre> <p>This functions format is <code>RemoveRows(<em>rowNumber</em>,<em>rowCount</em>)</code>. So in the above, I am saying, starting at row <code>4</code>, delete <code>1</code> record from my ColdFusion query <code>local.query</code>. Simple, yet very effective!</p> Order mySQL results in a predefined set list order http://www.stevemckeogh.co.uk/blog/2010/1/order-mysql-results-in-a-predefined-set-list-order/ 2010-01-04T10:45:13Z 2010-02-16T22:59:13Z <p>Okay, it's tricky to put in a title what I'm getting at here, so sorry if the title is a little vague :).</p> <p>What I want to show here is how to <code>order by</code> records in a custom way in mySQL. So for arguments sake, take a look at the below query:</p> <pre><code>select * from my_table where id in (2,1,4,3,5)</code></pre> <p>Now if I wanted the results to come out in that exact order <code>2,1,4,3,5</code> it's tricky to do without having some data in the database that will output it in that order (e.g. a position column or whatever).</p> <p>Well this is where the <code>find_in_set()</code> string function comes into play! To do exactly what I mentioned above, I'd edit the statement like:</p> <pre><code>select * from my_table where id in (2,1,4,3,5) <span style="color:green">order by find_in_set(id,'2,1,4,3,5')</span></code></pre> <p>The above tells mySQL to return the results in the order of id's <code>2,1,4,3,5</code>, voila!</p> <p>One note of caution, ensure you do not have spaces in your list, otherwise the desired effect will not work, e.g. the follow will not return the correct order: <code class="nowrap">find_in_set(id,'2, 1, 4, 3, 5')</code>, definitely worth remembering, because I was scratching my head when I encountered this the first time around (as ColdFusion decided it wanted to add the spaces to my var).</p> Vertically align a div to the bottom in css without tables http://www.stevemckeogh.co.uk/blog/2009/10/vertically-align-a-div-to-the-bottom-in-css-without-tables/ 2009-10-28T20:40:31Z 2010-02-16T22:42:31Z <p>One of the great things about the good 'ol <code>&lt;table&gt;</code> days was the ability to <code>valign="bottom"</code> elements on the page, this is also possible in css with div's... albeit not as thorough.</p> <p>If you want to vertically align a div to the bottom of it's container div, then the below would do the trick nicely:</p> <pre><code>&lt;style type="text/css"&gt; div.container{ width:200px; height:200px; background:#eee; position:relative } div.bottom{ width:100%; background:#ddd; left:0; bottom:0; position:absolute } &lt;/style&gt; &lt;div class="container"&gt;&lt;div class="bottom"&gt;some text&lt;/div&gt;&lt;/div&gt;</code></pre> <p>The above example will tell the inner div <code>div.bottom</code> to sit at the bottom of the outer div <code>div.container</code>. The only downfall with this is the outer container will need a specified height, as <code>height:100%</code> won't work in some browsers on a non specified height container and/or parent.</p> <p>The important part of the above is the <code>bottom:0</code>. This tells the browser to sit this element at the footer of it's parent at all times.</p> <p>Also, as the outer div is positioned relatively, in Internet Explorer, you will need a fixed outer layer (e.g. floated, absoluted) otherwise Internet Explorer will not push any content below it down.</p> Remove the dotted focus outline around hyperlinks with css http://www.stevemckeogh.co.uk/blog/2009/10/remove-the-dotted-focus-outline-around-hyperlinks-with-css/ 2009-10-19T15:17:47Z 2010-02-16T22:20:47Z <p>In most browsers, when you focus on a link you will see the indication outline that you have focused on the link. This can look rather ugly in some situations, and is easily removed in all browsers with one line of css.</p> <p>To remove the outline from your page, just add the below to your style block associated to the link you want to remove it from, like:</p> <pre><code>a{outline:none !important}</code></pre> <p>The above snippet, if placed in your stylesheet (or <code>style</code> block) will remove this outline from all hyperlinks in the site.</p> <p>It's definitely worth me mentioning that you should take careful consideration when deciding to do this, as it does have accessibility implications and should only be done in rare cases.</p> One line text without wrapping using css http://www.stevemckeogh.co.uk/blog/2009/9/one-line-text-without-wrapping-using-css/ 2009-09-06T15:47:17Z 2010-02-16T21:59:17Z <p>Although this may seem pretty basic, I have seen it asked a few times, so it's certainly worth blogging about.</p> <p>In some situations, you may want to restrict one line of text (usually a title) to be just that, one line of text to prevent any template height issues. Well its very easily done with some very simple css.</p> <p>Let's take the below for example:</p> <pre><code>&lt;style type="text/css"&gt; h1{ width:200px; margin:0; font-size:80% } &lt;/style&gt; &lt;h1&gt;This is some text I want to stay on one line&lt;/h1&gt;</pre></code> <p>This snippet of code will wrap the text to two lines by default, but to stop the text wrapping and not busting out of the template, change the above style block to:</p> <pre><code>&lt;style type="text/css"&gt; h1{ width:200px; margin:0; font-size:80%; <span style="color:green">overflow:hidden; white-space:nowrap</span> } &lt;/style&gt;</pre></code> <p>By adding the two green lines above, the title will never wrap to more than one line and it won't bust the width of it's container. Unfortunately this will only hide the text that flows beyond the <code>200px</code>, but that is better than a busted template right?</p> Internet whilst connected to VPN in OS X Leopard http://www.stevemckeogh.co.uk/blog/2008/12/internet-whilst-connected-to-vpn-in-os-x-leopard/ 2008-12-20T12:33:26Z 2008-12-20T12:33:26Z <p>Back in December 2007 I posted an <a href="/blog/2007/12/vpn-default-gateway-on-mac-os-x/">article</a> on changing the default VPN gateway in OS X to allow you to access the internet whilst being connected to a internet restricted VPN connection. This, however doesn't work for some OS X Leopard users (including myself) and you still cannot access the internet whilst connected to a VPN connection no matter what you do.</p> <p>Well after some playing around, I managed to get this all working fine in Leopard by making a small (and simple) change. So if you cannot access the internet whilst connected to some VPN connections in Leopard then try the following:</p> <ol> <li>Firstly, you need to find your DNS server, to do this open up System Preferences > Network and find the DNS server for your internet connection. So in my case, I select "Ethernet 1" and I will see my DNS server as 192.168.0.1</li> <li>Whilst still in Network, select the VPN connection you want to "fix" and click "Advanced". Under the "DNS" option, enter the DNS server you got from point 1 (in my case 192.168.0.1).</li> <li>Before leaving this area, select the "Options" tab and ensure the "Send all traffic over the VPN connection" checkbox is <strong>not</strong> ticked.</li> </ol> <p>Now close the System Preferences window and connect to you VPN connection, and hopefully you will be able to access the internet still... it works a treat for me!</p> AJAX Activity Indicators http://www.stevemckeogh.co.uk/blog/2008/5/ajax-activity-indicators/ 2008-05-08T10:14:00Z 2008-05-08T10:14:00Z <p>If you are in the need of a AJAX activity indicator icon then head on over to <a href="http://www.ajaxload.info" target="_blank" title="This link opens in a new window">www.ajaxload.info</a> and here you will find a place that has every indicator image you could wish for, and more importantly the option to tell the site what colour your website background is and it will generate the animated icon for you on the fly!</p> How to order results randomly in Oracle http://www.stevemckeogh.co.uk/blog/2008/4/how-to-order-results-randomly-in-oracle/ 2008-04-20T10:12:35Z 2008-04-20T10:12:35Z <p>Those familiar with MySQL may have used the rand() function before to order a resultset randomly. Well there is a just as simple method in Oracle, just with different syntax.</p> <p>To order your results in Oracle in a random order you use the dbms package (packaged with Oracle) called random. So a simple order random query would look like:</p> <pre><code>SELECT * FROM tableName ORDER BY dbms_random.value</code></pre> <p>That's it, your results will now be ordered randomly every time the query is run. But there's more to <code>dbms_random</code> than that though, you can also use it to generate random numbers or strings. Take a look at some of the examples below:</p> <p>Generate a random negative or positive number:</p> <pre><code>SELECT dbms_random.random FROM dual</code></pre> <p>Generate a random number between 1 and 9999:</p> <pre><code>SELECT dbms_random.value(1,9999) AS rand FROM dual</code></pre> <p>Generate a random UPPERCASE string of 10 chars:</p> <pre><code>SELECT dbms_random.string('U',10) AS rand FROM dual</code></pre> <p>Generate a random LOWERCASE string of 10 chars:</p> <pre><code>SELECT dbms_random.string('L',10) AS rand FROM dual</code></pre> <p>The dbms_random package can do a lot more than this, but they are a few examples that I use every now and then.</p> How to LIMIT results in Oracle http://www.stevemckeogh.co.uk/blog/2008/4/how-to-limit-results-in-oracle/ 2008-04-02T16:44:43Z 2008-04-02T16:44:43Z <p>Those familiar with MySQL and PostgreSQL will know about the <code>LIMIT</code> clause these database's have. For those not in the know, the <code>LIMIT</code> clause will limit your resultset to a specific number, it can also start your results of at a specific offset. So for example <code>LIMIT</code> 10 will restrict your results to 10 records, and <code>LIMIT</code> 2,10 will restrict your resultset to 10, but will start the results are row 2. This is great for pagination in your applications.</p> <p>Unfortunately Oracle doesn't have any such thing, and you have to use Oracles special <code>ROWNUM</code> column instead to limit your results. This is not as easy to use as the above, but does the same thing. You could always use ColdFusion's maxrows, but this is not wise on large recordsets as the database will have to pull back all records, only for you to show a select few of them. To use an offset in your resultset is even more complex, but thats for another article!</p> <p><code>ROWNUM</code> doesn't work how you would like it to either, Oracle assigns the <code>ROWNUM</code> value to all result columns before the <code>ORDER BY</code> has been complete. <code>ROWNUM</code> is also incremented only after it is given. This, therefore prevents a simple query like:</p> <pre><code>SELECT * FROM tableName WHERE ROWNUM <= 10</code></pre> <p>The correct way to use the <code>ROWNUM</code> in this situation would be:</p> <pre><code>SELECT * FROM ( SELECT * FROM tableName ORDER BY recordDate Desc ) WHERE ROWNUM <= :10</code></pre> <p>This will use Oracle's optimisers to pull back the top 10 results in the fastest way it can. To read more on how this works, have a read of this <a href="http://www.oracle.com/technology/oramag/oracle/06-sep/o56asktom.html" target="_blank" title="This link opens in a new window">Ask Tom article</a>. This article also goes in to depth on how to get pagination working with Oracle.</p> VPN in Windows Vista with a non-standard Subnet Mask http://www.stevemckeogh.co.uk/blog/2008/3/vpn-in-windows-vista-with-a-non-standard-subnet-mask/ 2008-03-29T20:19:53Z 2010-02-16T22:22:53Z <p>Windows XP never had this problem, if you connected to a VPN connection that didn't use the standard 255.255.255.255 Subnet Mask, it wouldn't matter, Windows XP would see this and make the change accordingly. Annoyingly, Windows Vista has a problem with this and it will default you to the 255.255.255.255 Subnet Mask anyway, therefore preventing you from seeing the VPN network.</p> <p>Well there is a way around this, it's not ideal, but it's the only fix I know of currently.</p> <p>Firstly connect to your VPN connection like normal, once connected successfully, open up a command prompt and type:</p> <pre><code>ipconfig</code></pre> <p>This will bring up several IP addresses, what you want to do is find the VPN connection on this list, it will usually be at the top like:</p> <pre><code>Connection-specific DNS Suffix . : IPv4 Address . . . . . . . . . . : 192.168.16.105 Subnet Mask . . . . . . . . . . : 255.255.255.255 Default Gateway . . . . . . . . :</code></pre> <p>Now take note of the last set of digits after the final full stop in the IPv4 Address row, in the case of the above its 105.</p> <p>Keep the command prompt open, and enter:</p> <pre><code>route add 192.168.16.0 mask 255.255.240.0 192.168.16.*</code></pre> <p>Replacing * with the digits you just remembered. The above example works for my VPN connection, and changing the Subnet Mask to 255.255.240.0, the other IP addresses will have to be replaced with the equivalent within your VPN connection, but I think it's pretty self explanatory.</p> <p>After pressing return, you should see:</p> <pre><code>Ok!</code></pre> <p>That means all was good and you should now be able to connect to your VPN network like usual.</p> How to know if a input type image has been pressed in ColdFusion http://www.stevemckeogh.co.uk/blog/2008/3/how-to-know-if-a-input-type-image-has-been-pressed-in-coldfusion/ 2008-03-28T11:56:07Z 2008-03-28T11:56:07Z <p>It's easy to know when a form has been submitted when you have only one submit button on your page, it's even as easy if you have more than one submit button on your page to know which one was pressed. But what about if you have more than one image button on your page, well it is just as easy, but from experience, I have found a lot of people don't know how to do this, so that makes this article worthwhile!</p> <p>With a standard <code>&lt;input type="submit" name="btn1" value="Go" /&gt;</code> you just look for the button name like: <code>&lt;cfif isDefined("form.btn1")&gt;&lt;/cfif&gt;</code>, and the same goes for multiple submit buttons.</p> <p>With <code>&lt;input type="image" src="image.gif" name="btn1" alt="" title="" /&gt;</code> it is just as easy, but you just need to add one more thing to your <code>isDefined()</code> and that is .x. So instead of <code>&lt;cfif isDefined("form.btn1")&gt;...&lt;/cfif&gt;</code> you will have <code>&lt;cfif isDefined("form.btn1.x")&gt;...&lt;/cfif&gt;</code>.</p> <p>You can look for .y instead if you want, but it makes no difference. The reason it works in this way is because when you press an image button, the browser sends the coordinates for that press instead of the button name. Then in ColdFusion, all you need to do is look for the coordinates, hence the x, y values.</p> How to kill a user's session in Oracle http://www.stevemckeogh.co.uk/blog/2008/3/how-to-kill-a-users-session-in-oracle/ 2008-03-25T15:39:51Z 2008-03-25T15:39:51Z <p>This has happened a few times to me, so it's worth jotting down how to fix it.</p> <p>When you want to drop a user/schema in Oracle, sometimes you get an error explaining that the user you are trying to drop still has a session and you are therefore prevented from dropping that user.</p> <p>Well this is remedied quite easily by running the below to kill that particular user's session:</p> <pre><code>SELECT sid,serial# FROM v$session WHERE username='<user>'</code></pre> <p>After getting your results from here, run the below:</p> <pre><code>ALTER system KILL SESSION '<sid,serial#>'</code></pre> <p>This will kill all the sessions associated to this user, effectively allowing you to know drop the user.</p> Getting the width and height of a swf in ColdFusion http://www.stevemckeogh.co.uk/blog/2008/3/getting-the-width-and-height-of-a-swf-in-coldfusion/ 2008-03-05T15:41:52Z 2008-03-05T15:41:52Z <p>Seeing as ColdFusion and Flash are owned by the same corporation (Adobe) you would assume there would be some kind of flash integration into ColdFusion (ColdFusion 8 especially), well you would be wrong, cos theres none... well none that allows you to get a width and height of a .swf anyway.</p> <p>Well fortunately, the guys over at <a href="http://www.alagad.com/" target="_blank" title="This link opens in a new window">Alagad</a> have created a free cfc that allows you to read the important information from a .swf file. The most usful part of this is the ability to get the width and height of a .swf, and it's all done in a couple of lines of code:</p> <pre><code>&lt;cfset flashInspector=CreateObject("Component","path.to.flashinspector").init(expandPath("flash.swf")) /&gt; &lt;cfset width=flashInspector.getMaxX() /&gt; &lt;cfset height=flashInspector.getMaxY() /&gt;</code></pre> <p>That's it, now you have the width and height of the supplied flash.swf file.</p> <p>You can <a href="http://www.alagad.com/go/products-and-projects/flash-inspector" target="_blank" title="This link opens in a new window">download</a> the .cfc here, and also make a donation to help the cause!</p> Mount a network share automatically in Mac OS X http://www.stevemckeogh.co.uk/blog/2008/2/mount-a-network-share-automatically-in-mac-os-x/ 2008-02-23T17:49:19Z 2008-02-23T17:49:19Z <p>I love OS X, I haven't once looked back from my switching days, but I still get a little frustrated by the way OS X handles network shares. In OS X all network shares feel as if they are exactly that, shares, and not part of your Mac. Whereas Windows felt different, it felt like the share was part of your PC and it was always there (on boot, after waking etc) and that made life a lot easier.</p> <p>Leopard has improved on its sharing abilities (with other Mac's or Windows PC's) in the way all network computers are seen on the sidebar, but this doesn't mean they are connected! For example, you may see your Windows PC on the left, but you have to physically click and connect for the share to be mounted to your Mac, this is frustrating, especially when I just want to boot my Mac and open Dreamweaver straight up and get coding.</p> <p>Before you actually mount the share, if I where to start up Dreamweaver, I wouldn't see my Windows 2003 server in my files list, so I would have to go and mount this drive then go back to Dreamweaver. You can add the mount to your login items, but then you get the folder popping up every time you boot (regardless of the "hide" checkbox being checked or not). So I done some research and found a great way to mount your shares on boot without interrupting you! This method works in OS X Tiger and Leopard.</p> <p>The way to do this is via AppleScript, with AppleScript you can write simple functions for OS X to understand, and even save them as Applications (.app) which I will show you here.</p> <p>So to mount a share automatically when you boot in to OS X, open up the Script Editor.app (it's in Applications > AppleScript). Now in this window you can start entering your AppleScript. Below is a snippet of my "mountnetwork.scpt" file:</p> <pre><code>tell application "Finder" activate try mount volume "cifs://WORKGROUP;Steve@WRIGHT/WEBSITES" end try end tell</code></pre> <p>What the above is doing is telling "Finder" to mount the Windows volume (cifs://). So my example above is mounting my Windows share named "WEBSITES" which is on my server called "WRIGHT" using a username of "Steve". I am also telling OS X that it is in a workgroup called "WORKGROUP".</p> <p>Once you have entered the details for your server, press the "Compile" button, as long as you get no errors you are ready to save this as an Application. Before saving it as an Application though, save it as a script first so you can return to it in the future if you want to add more shares.</p> <p>To save the script as an Application go to File > Save as and find the place you want to save it. Enter a name for it, and in the "File Format" drop-down select "application". Before pressing Save, it is very important you ensure you ONLY have the "Run Only" checkbox ticked, uncheck all the others. Without doing this, you will get the "Run" or "Quit" popup every time you run the Application.</p> <p>Once this has been saved, double click the .app and see if it mounts your share(s). If this was successful, simply drag the app into you Login Items and check the "Hide" box and you shares will mount on boot every time!</p> <p>If you are on OS X Tiger, when your Mac sleeps (if you allow that) the share(s) may disappear when your Mac wakes up, to fix this install the SleepWatcher app, with this you can tell OS X to do anything after it wakes from a sleep. Fortunately, Leopard doesn't have this problem.</p> Applying a css style to Internet Explorer 6 only http://www.stevemckeogh.co.uk/blog/2008/2/applying-a-css-style-to-internet-explorer-6-only/ 2008-02-10T15:17:07Z 2008-02-10T15:17:07Z <p>Due to the amount of bugs that seem to plague Internet Explorer 6, it is very useful to know how to specify a style to IE6 only. Well ironically, due to one of its many bugs, you actually can!</p> <p>One feature I use this for a lot is to get the min-height: style working in IE6, as IE6 does not know what this style is and will not put a height on the element at all. So to get round this, you apply the min-height: style as always to the element, then simply add a new block with this special IE6 only fix and add a height: to that. For example:</p> <pre><code>/* All browsers */ #mydiv{ width:100px; min-height:100px; float:left } /* IE6 only */ /*\*/ * html #mydiv{height:100px} /**/</code></pre> <p>The actual fix is the second part, by wrapping the style block with a <code>/*\*/</code> and a <code>/**/</code> then prefixing the style class with a <code>* html</code> you are taking advantage of the IE6 bug. All browsers will see this as a comment, and will not look in there, whereas IE6 will not see it as a comment and will apply the style to the page. Simple but very effective!</p> Margin bug in Internet Explorer 6 http://www.stevemckeogh.co.uk/blog/2008/2/margin-bug-in-internet-explorer-6/ 2008-02-10T15:00:33Z 2008-02-10T15:00:33Z <p>This fix has been around for a while, but I definitely think it is worth making an article for this as it still annoys me to this day, and I'm sure it will annoy other developers too.</p> <p>In Internet Explorer 6, there is a very weird bug when applying a <code>margin:</code> css value to a <code>float</code>: div. The bug makes IE6 render the margin to the wrong size that you specify in the stylesheet. So for example, a <code>margin:0 0 20px;</code> may actually add a margin height of 26px instead of the specified 20px or similar. This only occurs in IE6 and no other browsers (including IE7) seem to have this bug.</p> <p>This is very simple to fix though, all you need to do is add the following to your style block:</p> <pre><code>display:inline;</code></pre> <p>And that's it, the margin will render to the amount of pixels you actually specify, easy!</p> Alpha transparency on background png images in IE6 http://www.stevemckeogh.co.uk/blog/2008/1/alpha-transparency-on-background-png-images-in-ie6/ 2008-01-08T14:03:29Z 2008-01-08T14:03:29Z <p>I'm sure most people are aware of the Javascript hack that will add alpha transparency to any png images on the page within an <code>&lt;img&gt;</code> tag in Internet Explorer 6. This is great, but what about background images? The Javascript hack will not pick those up, so you will have to find another way to do this... fortunately there is a way.</p> <p>As Internet Explorer 7 has implemented the alpha transparency to png images (at last!) the problem now only occurs in IE6, so you only need to apply this for IE6, that also, is easy to get round.</p> <p>Here is how to do it, using our example alpha transparent png file alpha.png.</p> <pre><code>#mydiv{ width:100px; height:100px; background:url(alpha.png); float:left }</code></pre> <p>Now the above will work perfectly in all browsers apart from IE6, instead you are likely to see a gray background... or maybe even a black one, either way it will not be partially transparent like we want, so all you need to do is add the below:</p> <pre><code>/*\*/ * html #mydiv{ background:none; filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='alpha.png') } /**/</code></pre> <p>Firstly, the above style is wrapped with <code>/*\*/</code> and <code>/**/</code> and started with a <code>* html</code>. This makes the style only visible in IE6, all other browsers will ignore this (including IE7).</p> <p>So now that we know only this block can be seen by IE6, we tell it to set the background image to <code>none</code> and apply the special IE only filter to set the alpha.png to be alpha transparent. It is very important that you add the <code>background:none</code> to this style block, otherwise the background that has been set above will just overwrite the filter and you will still see the gray/black background.</p> <p>As IE6 is still widely used and not taken over by IE7 fully yet, I feel it's very important not to forget these users, and to continue testing your site's in IE6... I know I do!</p> <p>Also I feel it's worth me pointing out, I am completely aware of the <code>opacity:.5</code> and <code>filter:alpha(opacity=50)</code> styles.</p> ColdFusion memcached client http://www.stevemckeogh.co.uk/blog/2008/1/coldfusion-memcached-client/ 2008-01-04T11:31:42Z 2008-01-04T11:31:42Z <p>I've already talked about the advantages of memcached <a href="/blog/2008/4/memcached-for-windows/">here</a>, but I never mentioned how to get it in to your ColdFusion applications. Fortunately most of the hard work has already been done for you by <a href="http://theshayne.com/" target="_blank" title="This link opens in a new window">Shayne Sweeney</a>, as he has created the ColdFusion memcached client for you.</p> <p>Once you have memcached installed on your server (Linux or Windows) you then need to get it working with your code.</p> <p>Firstly, go to the <a href="http://memcached.riaforge.org/" target="_blank" title="This link opens in a new window">memcached ColdFusion client page</a> and download the project. Unzip the project and you should see the following:</p> <pre><code>com resources tags MemcachedFactory.cfc</pre></code> <p>The first thing you need to do is move the com, resources and MemcachedFactory.cfc files to a /memcached/ directory in the root of your web app leaving you with just the tags folder.</p> <p>The tags folder contains the main custom tag that gets your site connected to the memcached server you have installed. So move the cached.cfm file within the tags folder to your servers CustomTags directory, I renamed it to memcached.cfm, but thats up to you. Now you have the use of a <code>&lt;cf_memcached&gt;</code> tag. If you don't have access to your servers CustomTags directory for some reason, then you can put the file in your site somewhere and use the <code>&lt;cfmodule&gt;</code> tag instead, its entirely up to you.</p> <p>Thats the hard bit (if you like) done, now all you need to do is use it! The first thing to do is cache the MemcachedFactory.cfc in the application scope, so enter something like the below into your Application.cfm/cfc:</p> <pre><code>&lt;cfif not structKeyExists(application,"memcachedFactory")&gt; &lt;cfset application.memcachedFactory=createObject("component","memcached.MemcachedFactory").init() /&gt; &lt;/cfif&gt;</code></pre> <p>Now to cache a simple query for example, consider the below:</p> <pre><code>&lt;cf_memcached variable="myquery" key="myqueryKey" timeout="86400"&gt; &lt;cfquery datasource="datasource" name="myquery"> select * from tableName &lt;/cfquery&gt; &lt;/cf_memcached&gt;</code></pre> <p>Firstly, the <code>variable="myquery"</code> tells memcached what element on the page to cache, this variable will usually be your query name, but you can cache pretty much anything with a variable name on the page, in this case we are caching our query, which you will see also has a name of <code>myquery</code>.</p> <p>Then we have the <code>key="myqueryKey"</code>, this is your unique key for memcached, this key can be any alpha-numeric value you want, but must be unique to your application otherwise you will start pulling out results for other queries. Every time your site calls this custom tag, memcached will check if it has a unexpired key called <code>myqueryKey</code>, if it does it will send that back to your code, if not, it will go to the database, store the resultset and then spit that back to your code.</p> <p>Finally there is the <code>timeout="86400"</code> attribute, this is just your timeout for the cached record in seconds. In this case, we are caching the query for <code>86400</code> seconds (24 hours).</p> <p>The <code>&lt;/cf_memcached&gt;</code> is not required at all, but I like to put it there to contain the item I am caching, this makes things easier to read in the future.</p> <p>Once this is done, have a look through the cfc and you will see all the other things that memcached can do. I also have a custom tag called memcacheddelete.cfm, which when called, will delete a key from memcached ready for it to be hashed again. There are many other methods in the cfc that are also very useful.</p> memcached for Windows http://www.stevemckeogh.co.uk/blog/2008/1/memcached-for-windows/ 2008-01-04T11:02:29Z 2008-01-04T11:02:29Z <p>I'm in the process of building a huge site, that could potentially have 2+ million registered users, therefore I need to have some kind of advanced caching going on for my Oracle queries. Sure, ColdFusion query caching is ok, but I don't have much control over it, and it's not as advanced as memcached, as memcached's sole purpose is to cache... and it's FAST!</p> <p>The <a href="http://www.danga.com/memcached/" target="_blank" title="This link opens in a new window">memcached site</a> doesn't boast too much about the Microsoft Windows version of memcached, but there is a port, you just need to look for it... or you can follow <a href="http://jehiah.cz/projects/memcached-win32/" target="_blank" title="This link opens in a new window">this link</a> straight there.</p> <p>To tell you what memcached does (for those not in the know) here is how <a href="http://www.danga.com/" target="_blank" title="This link opens in a new window">Danga Interactive</a> (the developers of memcached) themselves describe it:</p> <p><em>"memcached is a high-performance, distributed memory object caching system, generic in nature, but intended for use in speeding up dynamic web applications by alleviating database load."</em></p> <p>memcached is very easy to implement, and once in your code you can speed up large database queries considerably!</p> <p>As memcached simply collects the the query data, it doesn't care if you are using Oracle, MySQL, SQL Server etc, it will take the results of the query and cache it with a unique key (that you supply). When you make a call for the same query again, memcached will check if it has a cached result for that query, if so it will spit the cached version out and never touch the database.</p> <p>memcached is very flexible, you specify the timeout for the cached query, if you want to clear the cache for a specific key (or all keys if you want) then just tell memcached in your code and it will clear the cache for the key, the next visitor to run that query will then rehash that key until the timeout is reached.</p> <p>memcached can be setup to run with any language, you just need to get it in there. I personally have only used it with ColdFusion, but head over to the <a href="http://www.danga.com/memcached/" target="_blank" title="This link opens in a new window">memcached site</a> and have a read about ways to get it working with your site.</p> Search engine safe URLs without mod_rewrite or ISAPI Rewrite http://www.stevemckeogh.co.uk/blog/2008/1/search-engine-safe-urls-without-mod_rewrite/ 2008-01-03T20:39:39Z 2008-01-03T20:39:39Z <p>Nowadays it's very important to make your site as search engine friendly as possible, this means not only making your code "acceptable" to search engines, but also ensuring the URLs in your site are tidy and don't contain too much query string data.</p> <p>So for example, the below would not be ideal:</p> <p>http://www.domain.com/?id=1&title=my-page</p> <p>Now with Apache's mod_rewrite or ISAPI Rewrite for IIS you can convert the above to something similar to:</p> <p>http://www.domain.com/1/my-page/</p> <p>Not only does the above look much neater, Google will appreciate it more and index it with minimal fuss. Thats all fine and well if you have mod_rewrite/ISAPI Rewrite etc running on your server, what about if you don't?</p> <p>Well you could make ColdFusion turn all pages into .html files via the <code>&lt;cfhttp&gt;</code> syntax, but that is bulky and not ideal. There is another way however, its not as complete as using mod_rewrite or ISAPI Rewrite, but if its all you have it works fine.</p> <p>The way to do it is to use <a href="http://developer.fusium.com/tools/sesfaq.cfm" target="_blank" title="This link opens in a new window">SESConverter</a>. Essentially all SESConverter does is replace all query string ?, & and = with a / therefore making the example above look something like:</p> <p>http://www.domain.com/index.cfm/id/1/title/my-page</p> <p>It's very easy to implement into your site as well, all you need to do is download the sesconverter.cfm <a href="http://developer.fusium.com/tools/sesfaq.cfm" target="_blank" title="This link opens in a new window">from here</a>, and put this on your server somewhere. Now in your Application.cfm/cfc add the following:</p> <pre><code>&lt;cfset SESdummyExtension=".cfm" /&gt; &lt;cfset SESrBaseName="baseHREF" /&gt; &lt;cfinclude template="sesconverter.cfm" /&gt;</code></pre> <p>Now this will be called from all your .cfm pages, the final thing to do is to add the <code>&lt;base&gt;</code> tag to your header, so just add the below to the <code>&lt;head&gt;</code> of your document:</p> <pre><code>&lt;cfif isDefined("variables.baseHref")&gt; &lt;cfoutput&gt; &lt;base href="#variables.baseHref#" /&gt; &lt;/cfoutput&gt; &lt;/cfif&gt;</code></pre> <p>Now try creating a similar link to the above and it should take you to the same place the "ugly" URL does! Read the <a href="http://developer.fusium.com/tools/sesfaq.cfm" target="_blank" title="This link opens in a new window">SESConverter FAQ</a> for more details.</p> Mac OS X style search fields in Safari http://www.stevemckeogh.co.uk/blog/2008/1/mac-os-x-style-search-fields-in-safari/ 2008-01-01T18:34:46Z 2008-01-01T18:34:46Z <p>This is quite a neat little feature that I have used on a few sites now, unfortunately this only works on Safari, but its worth putting it in for that alone.</p> <p>For those who don't know, or are unsure what I am talking about, when I say "Mac OS X style search fields" I mean the curved form field with the small magnify icon to the left that is native to OS X</p> <p>These style search fields are used a lot on OS X (Safari, iTunes etc) and Apple have their own html syntax to get this into web pages. As this only works in Safari, you will have to have an alternative for other browsers, but its easy to capture this in the code (well I will show you in ColdFusion).</p> <p>To get this field into your .cfm page, look at the following:</p> <pre><code>&lt;cfif lcase(cgi.http_user_agent) contains "safari"&gt; &lt;!--- safari ---&gt; &lt;input type="search" autosave="bsn_search" results="5" name="kwd" /&gt; &lt;cfelse&gt; &lt;!--- non safari ---&gt; &lt;input type="text" name="kwd" /&gt; &lt;/cfif&gt;</code></pre> <p>So as you can see from the above, it's just a simple <code>&lt;cfif&gt;</code> to check whether the browser is Safari, if so it shows the special Safari only syntax, otherwise it shows the non Safari version.</p> <p>The Safari only version not only has the appearance of the OS X style search fields, but it's functional as well. The small magnifying glass on the left will drop down and show the user any recent searches they have made on the site, the <code>results="5"</code> defines the amount of results to pull back here.</p> SSL without an SSL certificate with SelfSSL on IIS http://www.stevemckeogh.co.uk/blog/2008/1/ssl-without-an-ssl-certificate-with-selfssl-on-iis/ 2008-01-01T14:47:36Z 2008-01-01T14:47:36Z <p>This add-on for IIS (Internet Information Services) is invaluable for me, and I'm sure it will prove very useful for fellow web developers!</p> <p>Before I knew about this, if I had to build a secure area of a site (https://) I would setup a new website in IIS with a slightly different name so I could test that my site enters and leaves the secure area properly. This way was ok, but certainly not ideal... especially if sessions where involved as the new "domain" would lose the session. So I done a search on this and found an official Microsoft add-on for IIS called SelfSSL, it's bundled with the IIS 6.0 Resource Kit!</p> <p>Firstly, download the <a href="http://www.microsoft.com/Downloads/details.aspx?familyid=56FC92EE-A71A-4C73-B628-ADE629C89499&displaylang=en" target="_blank" title="This link opens in a new window">IIS 6.0 Resource Kit Tools</a> from the Microsoft website. Then run the iis60rkt.exe from your server and follow the installation instructions. As SelfSSL if part of the Resource Kit bundle it will ask you want items you want to install, I personally selected the SelfSSL tool only, but feel free to select what you want, but you will not need any of the other tools to allow SelfSSL to run.</p> <p>Once this is installed, you should be ready to apply the "SSL Certificate" to your development site(s). To do this:</p> <ol> <li>Open the Internet Information Services (IIS) Manager. Select the nodes on the left and get to the Web Sites option and make a note of the Identifier number next to the site you want to apple the SSL to. The Identifier should be a 1 - 10 digit number.</li> <li>Go to Start > All Programs > IIS Resources > SelfSSL > SelfSSL and you should be presented with a command prompt.</li> <li>Now this new command prompt shows you all the options for SelfSSL, so its pretty straight forward, but to setup SSL for the site you selected in point 1, you would type something similar to:</li> </ol> <pre><code>selfssl.exe /T /N:CN=&lt;computer name&gt; /S=&lt;identifier&gt;</code></pre> <p>Note: The /T is important, without this you may be prompted to accept the SSL certificate everytime you go to the secure area of this site in each new session.</p> <p>Now when you go to https://domain.local you should see the page you want to see. You may be asked to accept the certificate the first time, make sure you accept this and you should be fine.</p> VPN Default Gateway on Mac OS X http://www.stevemckeogh.co.uk/blog/2007/12/vpn-default-gateway-on-mac-os-x/ 2007-12-07T14:03:36Z 2007-12-07T14:03:36Z <p>I'm sure 95% of Mac OS X users are aware of this feature, but for those 5% who are not (I was one of them when I made the switch from Windows to Mac) here it is.</p> <p>When setting up a VPN connection in Windows, I always had to tell the VPN connection <strong>not</strong> to send traffic through that connection, but instead use my Internet connection for this. By default, Windows told the VPN connection to send all traffic over the VPN connection.</p> <p>To disable this, you would have to go to VPN Connection > Networking Tab > Internet Protocol Version x > Properties > Advanced and you would see the checkbox here, ensure it is unchecked and you are sorted.</p> <p>Well when I switched to OS X, I couldn't find this. I didn't look too long tbh, I ended up googling it and found it that way. But for those that don't know, you can find the equivalent check box by doing the following:</p> <p>Open up Internet Connect and select the VPN connection you want to add this option to. Once selected, go to the "Connect" menu at the top and select "Options". On here you will be presented with several checkboxes, uncheck the "Send all traffic over VPN connection" and there you have it!</p> <p>Pretty simple I know, but I felt it was worth posting this for people who are new to OS X.</p>