CSS Round Corners

Note: this post has been moved from the yosle.com blog, which I am in the process of taking down.

Round corners. Something that should be easy, right? Not so much. It seems they were left out of the CSS (less than 3) specification. No matter, there are a couple of ways to hack them out and make them look good. Basically there are two techniques: layering a few empty tags, and using images. There are some ways to do it with javascript as well, but I wont cover them because javascript is unnecessary. The layering technique is the most concise and clean, IMO, so that’s what this post will focus on.
Read More »

Simple web sites with django == win

Last night I put the main benogle.com site up. I have been looking for an easy way to create a simple website for a while. All I wanted was a couple things: quick setup with low cruft, pages editable from the browser, and quick, easy extension with god like power. Making a website is such a common occurrence, you’d think there would be a whole heap of options available that are stupid easy to use. I bet you are thinking, “gee, there are tons of CMS apps out there!” You’re right. I have used Typo3, textpattern, WordPress, and I have evaluated even more of them. Each one has been too heavy. They want to do too much in all the wrong places. On top of that, extension requires digging through their obscure plugin API and scouring their forums for something that should be simple. Oh, the pain.

I am happy to say that I have finally found a solution: Django. While I am sure it excels in building large-scale apps, it has been a completely perfect tool for creating a simple website such as benogle.com. I am surprised that, despite having never used Django before, it took a little over 6 hours (spread over several days) to construct, plus a couple hours for writing content. Wow! It took longer to build the theme for this WordPress blog! I recently built a site with about the same complexity for a family member with textpattern. I have four to five times more time and effort in it.

Read More »

jQuery pong

I like jQuery. A lot. The only thing I like more than jQuery is the community of crazy plugin developers. It reminds me of the python community: anything I need to do, there is a module, and the modules are pretty easy to use. So I thought I would add to the mix.

I wanted to release something that would take the ‘web 2.0′ world by storm. Something that any jQuery jockey could include in his/her app and boost productivity at least by 20%. So I thought, “dude, new-school thought believes downtime, R&R, and even games increase productivity.” Then I pondered. And I pondered. And while I was pondering, I totally made jquery pong (ok, so I retrofitted gameplay from one I found).

Here is one with all the defaults:

The code:

$(document).ready(function(){
    $('#pong1').pong('circle.gif');
});

And here is one in which you will lose:

The code:

$(document).ready(function(){
    $('#pong2').pong('circle.gif',{
        ballSpeed: 10,
        compSpeed: 10,
        playerSpeed: 2,
        paddleHeight: 20
    });
});

Here are all the options:

{
    targetSpeed: 30,  //ms
    ballAngle: 45,    //degrees
    ballSpeed: 8,     //pixels per update
    compSpeed: 5,     //speed of your opponent!!
    playerSpeed: 5,   //pixels per update
    difficulty: 5,
    width: 400,       //px
    height: 300,      //px
    paddleWidth: 10,  //px
    paddleHeight: 40, //px
    paddleBuffer: 1,  //px from the edge of the play area
    ballWidth: 14,    //px
    ballHeight: 14,   //px
    playTo: 10        //points
}

Download it and you’ll need the ball too. Have fun!

Use Wordpress custom fields for your meta tags

Today I realized my posts needed proper jargon in the description and keywords meta tags for uber SEO magic. What is the ‘right’ way to do this in WordPress? I found a bunch of plugins and other complicated methods, but I thought there should be an easy way with custom fields. I ended up on a forum post, which was exactly what I was looking for. You just create a couple custom fields: description and keywords, then print out the values of the fields in the header. So I dumped this into my theme’s header.php:

<meta name="description" content="<?php if(get_post_meta($post->ID, "description", true) !='' ) echo get_post_meta($post->ID, "description", true); else bloginfo('description');?>" />
<meta name="keywords" content="<?php if(get_post_meta($post->ID, "keywords", true) != '') echo get_post_meta($post->ID, "keywords", true); else echo strtolower(get_bloginfo('name'));?>" />

It works on the single post page, but it does not properly display the default on aggregation pages like the front page. This is fixed by adding the is_single() function to the if statements:

<meta name="description" content="<?php if(is_single() && get_post_meta($post->ID, "description", true) !='' ) echo get_post_meta($post->ID, "description", true); else echo 'My description';?>" />
<meta name="keywords" content="<?php if(is_single() && get_post_meta($post->ID, "keywords", true) != '') echo get_post_meta($post->ID, "keywords", true); else echo 'my, keywords, here';?>" />

Yay.

REMPL: push playlists to remote WinAMP install

Here’s the question: how do I control a box running WinAMP over my little home network? I have a music server box in the spare bedroom running sockso to serve up the ol’ music collection, and I have a stereo in the living room controlled by a laptop that usually plays music from the previously mentioned server via WinAMP.

The real problem is that I am really tired of getting off my booty, walking alllll the way to the laptop, sitting awkwardly on the edge of the coffee table, and hunching over to find something. Ugh! There must be a better way. I want to control the stereo laptop via some other machine on the network, dammit! Ideally WinAMP would be able to run as a server on the stereo machine, then the WinAMP instance on another machine would have some ‘run as client’ setting that points to the stereo laptop. Then I could just use WinAMP like normal, but have the awesomeness of it running on my stereo. I got all excited when I heard about WinAMP remote, thinking it was this functionality. But no, my enthusiasm was curbed when I found out it basically does what sockso does for me. No good.

So I hunted for a plugin to do something similar and I actually found quite a few. Unfortunately, most looked pretty cheesy or were dead. I eventually settled on AjaxAMP. It is pretty cool in that it is a webapp that is basically a stripped down version of winamp. But it doesn’t totally fit the bill because it is basically a stripped down version of winamp in a browser. It has no support for importing playlists, I can’t browse the internet radio stations, and there is, of course, no sockso integration. I just cant win, man.

The good part is that it is all Ajax-y so each time I, say, add a song to the playlist, some javascript makes a request to the server running on the stereo machine and says “hey stereo, add this song.” Yay. And his JS is not compressed so I was easily able to figure out how to use the params for each command. Double yay. All I needed to do was write a little library that makes the same requests for playlists from sockso and my beloved somafm.com.

My creation is a python script called rempl (remote playlist). You call it by specifying your AjaxAMP server and the playlist to push (pls or m3u) as params. It will then play or enqueue the playlist. Example:

python rempl.py myplaylist.pls

Ok, so now I could add a local playlist to the remote WinAMP instance, but it was too cumbersome. From sockso, I’d have to download the playlist, then run the script on the playlist. The easiest fix I could think of was to run the script as a helper app in the browser for m3u and pls files. Firefox errors out when just running a py script as the helper app in windows, so I wrapped it in a batch file. The only problem is that firefox starts the batch file in the firefox dir, so the path to the python script must be absolute. It sucks, but you’ll get over it.

How to use it

Install AjaxAMP on your stereo machine, then download rempl (project page).

You can use it from the command line:

python rempl.py -s http://192.168.1.101:5151 myplaylist.pls

add the ‘-e’ param to just enqueue:

python rempl.py -e -s http://192.168.1.101:5151 myplaylist.pls

Or you can use it with a browser:

If your client machine runs windows, open up the rempl.bat file from the download and edit AJAXAMP_ADDR to the url of your AjaxAMP machine, and edit REMPL_PATH to whereever you put the python script. Then in firefox, open a playlist (eg. somafm.com/play/indiepop for pls), click the Browse button, and find the rempl.bat file you edited. The file dialog ignores bat files, so you will need to find the dir that holds rempl.bat, then type rempl.bat into the filename box. Check the ‘do this from now on’ checkbox, click ok, and listen to the awesomeness of your stereo changing.

If you are using linux or a mac, first set the DEFAULT_SERVER var in rempl.py to your AjaxAMP server. Make the .py file executable (chmod u+x rempl.py), then in your browser, browse to a playlist file (eg. somafm.com/play/groovesalad), then open it with rempl.py and check the ‘Do this automatically from now on’ box.