Advanced CSS web design is not for the faint of heart or the easily annoyed

January 31, 2010

cssHow many times have you looked at a block of CSS being used on your site and wondered what in the heck is going on with all that? Is all that stuff really necessary? Did whoever put all this crap together really know what they were doing? Should I dare modify it?

Though quite functional with CSS technology, I am far from being a CSS expert but after looking at many style sheets I am left wondering what ever happened to the concepts of code reuse (at the very least implying readability,) compactness, and maintainability.

I’ve seen Wordpress themes that come with 2000 plus lines of CSS. Through experience I now tend to avoid those like the plague as they tend to break when upgrading browsers or your CMS software. Clean, compact, straightforward CSS is what you want. Granted, a lot of different fancy web design features will require a lot of CSS and in those instances look for adequate documentation.

If you simply load a nice theme you like with no plans of ever customizing it, these concerns may not seem important. But if you like to continuously improve or customize your site, rule out those themes with unruly style sheets regardless of how much you like how it looks. Follow this advice and you will save yourself a ton of headache down the road.

And speaking of analyzing CSS…

In technology terms, Douglass Bowman’s article Sliding Doors of CSS written way back in 2002 is an ancient document. However, if you are interested in a great CSS tutorial that steps you through the mind-numbing intricacies involved in developing an advanced design feature using CSS the article is one of the best I’ve read. I gained useful insight into the shenanigans used by these CSS gurus to accomplish cool web design layouts.

On the other hand, this excerpt…

Keen eyes may have noticed white tab corners showing up in the previous example. These opaque corners are currently preventing the image in the back from showing through the left corner of the image in front. In theory, we could attempt to match the corners of the tab images with a portion of the background behind them. But our tabs can grow in height, which pushes the background behind them lower, shifting the background color we tried to match. Instead, we change the images, making the corners of our tabs transparent. If the curves are anti-aliased, we matte the edges to an average of the background color behind them.

Now that the corners are transparent, a piece of the right-side image shows through the corner of the left-side image. To compensate for this, we add a small amount of left padding to the list item equivalent to the width of the left-side image (9px). Since padding was added to the list item, we need to remove that same amount from the anchor to keep the text centered (15px - 9px = 6px):

…clearly demonstrates why I don’t create CSS layouts from scratch.

  • Share/Bookmark

Wordpress drill-down admin pages II

January 18, 2010

wordpress-logo-300x300I never did do a follow-up on the Wordpress drill-down admin menus post. A lot of people continue to hit that article so I’ll take the time to give an example of how I easily resolved the issue.

The problem was that after an upgrade to Wordpress Mu v 2.8.4a all my dynamically created, drill-down admin pages quit working because they now needed to be registered with Wordpress for — completely understandable — security reasons.  As far as I can tell, the only way to register an admin page is through the menu system. Since I don’t want my drill down pages to be on the menu I needed a better way to do it.

One solution suggested was to just use the registered menu page as the callback to handle requests and that is for the most part what I did. The only issue with the solution is that the callback page has to also serve all the content since it can’t request an admin page that is not registered. Using one page to parse all requests and serve the appropriate content will get unwieldy for anything but the simplest of applications and if your application was that simple you wouldn’t be trying to figure out how to add custom drill-down admin menus.

I like modularity and easily managed code so my philosophy is that multiple small files are better than one huge file. I needed a way to solve the problem without breaking my philosophy or changing a lot of my existing code, which was already in multiple small files.

The idea is to build a container page to register on the admin menu and have the container page decide on which code to include based on analyzing the url. The included code can then handle and GET or POST requests and serve the appropriate page output.

<?php
/*
 * Descrition: gcgc admin page. This is the main container page
 * for all admin panels. All POSTS and GETS from all pages route
 * through this page and are handled by the appropriate included file.
*/
global $gcgc_Manager;
echo $gcgc_Manager->getHeader();
//analyze the url to determine which page to load

if (isset($_GET['panel'])){
    switch ($_GET['panel']){

    	case 'cache-admin' :
    	    include (dirname(__FILE__)."/gcgc-admin-cache.php");
    			break;

    	case 'vector-admin' :
           include (dirname(__FILE__)."/gcgc-admin-vector.php");
           break;

    	default :
           include (dirname(__FILE__)."/gcgc-admin-home.php");
    }
}else{
    include (dirname(__FILE__)."/gcgc-admin-home.php");
}

$gcgc_Manager->getFooter();
?>

I kept the above example brief but you can imagine that there can be an unlimited number of admin pages. And this way I didn’t have to change the included files at all — all I had to do was add the ‘&panel=’ parameter to existing request urls and problem solved.

  • Share/Bookmark

iPhone, Droid, Pre, Nexus One breakdown and comparison

January 6, 2010

Courtesy of BillShrink.com

Nexus One vs iPhone, Droid & Palm Pre

Short and sweet: The multitasking is going to be an issue with the iPhone as well as the lack of expandable memory.  I would expect both issues to be addressed in a soon-to-be-released upgrade. I mean, they pretty much have to, right?

Also if you take photos with your phone 5 megapixels is a significant improvement over 3 mp. Don’t let anyone tell you different. There may not be a big difference between 12 megapixels and 10 but if you take a lot of pictures you will be happier with more resolution at image editing time,especially when cropping.  If you don’t take pictures don’t say you never will; camera phones take ridiculously good images in many situations.

Total cost of ownership is kinda surprising since I’ve never seen the figures before.  T-Mobile’s Nexus One  with its outrageous talk time seems to be the best deal if the network is decent in your area.

Seen on Twitter

  • Share/Bookmark

The Internet is my snippets database

January 3, 2010

Like everyone who codes for a living I will lift a snippet of code from a website. Usually it’s very generic code — as most code is — and I never give it a second thought. There are only so many ways to iterate an object. A good portion of my Internet code searching is to look for code I need not because I don’t know how to do it from scratch but because I don’t want to have to figure out how to do it from scratch in yet a new language.

Although there is no reason for most programmers to ever write a sort since sorting is built in to everything these days, a sort would be a good example. Back in the day a programmer would find him or herself needing to sort things all the time and you could not make a decent living typing out a brand spanking new quicksort every time you needed one. So you figured out how to write any particular sort only once per language and saved the code for later reuse.

A more modern example would be something like this:

    defaultHandler=function(defaults,params) {
      var i;
      for (i in params) {
          defaults[i]=params[i];
      }
      return defaults;
    }

This powerful little bit of Javascript can be dropped anywhere you need a list of default parameters to be merged with a list of user submitted settings. If you are being efficient about your work you are not going to re-type that code every time you use it; you are going to cut and paste it.

So, like many older professional coders, I have a database with reusable code snippets that I have built up over the course of more than two decades in the business. I have snippets for every sort algorithm you can name: the quicksort, heap sort, bubble sort, merge sort, selection sort, insertion sort ; name and address validators/formatters; date/timezone transformations; list processing; form validation; dynamic tables; and cool tricks. When I need to do something which I have done already a dozen times I simply copy and paste from my vast snippets database, never wasting time re-writing the same code more than once.

That was then; this is now. The problem is that I have all these snippets archived in @formula language, LotusScript, VB, and a bit of Javascript whereas today I need PHP, Perl, Java, and advanced Javascript frameworks like jQuery. I could find the code in my snippets database that does the same thing and then port it over to the new language but why do that when almost any code snippet can be found in under a minute with a deft Google search? I haven’t even used my snippets database in half a decade. The Internet is now my snippets database. I found the above Javascript snippet here, for example, while looking for some sample JavaScript to pass different object types as function parameters.

I haven’t carried a technical reference book to work in almost ten years. I don’t even use them at home anymore. The Internet is now my technical reference library.

  • Share/Bookmark

Firefox session restore: Just a little bit sweeter

December 19, 2009

The new Firefox session restore functionality that popped up a couple of updates ago is quite nice and has introduced a slight improvement to my workflow.

I don’t know about most of you but the minimum Firefox windows I have open is four and the aggregated number of open tabs is near a dozen. And that’s just at start up. After a few hours, not mention a day or two, I may have 30, 40, 50 tabs open in the four windows. Probably not more than 50 but I don’t know for sure.

This hyper surfing results from researching technical issues and when I find applicable information I want to leave it up for reference until the issue is resolved or until the info is deemed not relevant. There is nothing worse than having to waste time re-finding a drop of information in the ocean of technical documentation through which you have been wading for the past several hours, or days.

Well no software is perfect and as good as it is, Firefox and the applications it hosts do leak memory. Some a lot more than others. System requirements at startup are about 400 Meg of available RAM. At the height of a work session, with many open tabs, RAM usage will swell to 600-800M. After a few days without restarting RAM usage will go above a Gig and closing everything but the startup configuration still consumes over 600 Meg. The leakage filled up a 200 Meg barrel.

fire-kill-process

For this reason, as you all know, you have to restart Firefox from time to time to keep things perky, and operational. This is where the Firefox session restore comes in handy.

What I use to do when I needed to restart was go through every tab and close all the pages that I no longer needed, bookmarking ones that I might need again (which I hate doing because it results in a bookmark nightmare over time.) Then instead of closing Firefox normally — this is the little trick — open the task manager, click the processes tab, and kill the Firefox process. Firefox will immediately close.

When Firefox restarts it thinks it is recovering from a crash and will give you the option to restore the previous session, opening all your windows and pages they way you left them. Pretty sweet huh. There may be another way to accomplish this same thing, but it cant be as easy as this method.

And it just got a little easier with a simple check-box prompt improvement. Now I don’t have to go through the tedious process of closing the tabs I don’t need prior to restarting. At startup after a crash, Firefox now prompts with a selection of pages that were open at the “crash” and you can tick off the ones you don’t want.

firefox-session-restore

Just a little bit sweeter.

  • Share/Bookmark

AOL rebranding according to my advice

December 13, 2009

In recent posts I poo-poo’d the thinking of current medial moguls vis-a-vis the Google Myspace deal as well as Rupert Murdoch’s plans to charge for their content. Now at least someone is catching on and is not intent on self-destruction as they cling on to the old way of doing things.

Here is what I said in early Nov (and numerous times before):

Content is king on the Internet. Want to improve your traffic, improve your content. Since users create the content at MySpace, it becomes essential to attract users who can consistently generate quality pop content. Even if you have to pay to get them.

Here is what AOL CEO Tim Armstrong said in early December:

Because AOL is content, the brand has to be like content: fluid, flexible, and changeable. It exists as a host for new innovations and new content experiences. In a world where people believe what you do and not what you say, it is these new experiences that will define this brand and people’s perceptions of it. AOL Seed is the first example of this. Here AOL are pioneering the content economy with a publishing platform that will allow budding creatives to publish, find an audience for their work, and make money doing so.

Media outlets that try to own and or control submitted or hosted content to their sole benefit are in for big trouble over the coming years, especially if that tactic is essential to their core business model. Think recording industry.

Yeah, maybe AOL use to suck, but now they plan to share the wealth with those who actually have a talent for creating engaging content. If AOL management can pull it off, don’t be surprised if this model is a raging success.

Rewarding individual talent is preferable to powerful people making tons of money simply because they have power and money. I’m actually quite put out with the latter.

  • Share/Bookmark

Brad & Beyonce Turkey

December 10, 2009

Check out this Wordpress blog that is comprised primarily of nothing but Brad and Beyonce Turkey’s Twitter feeds. Interesting concept, off-beat subject mater. Why are they doing it?

We looked after our Turkeys too well, and got attached. Help us decide which one to keep. The one with the most to live for by Christmas will be saved.

  • Share/Bookmark

Browsing through the help wanted ads

December 9, 2009

Regular visitors know I love making fun of online job postings. Here’s a good one:

Responsible for complex process automation of the systems management applications as well as integration to create interoperability between other applications. The applications include; HP OpenView for Windows (HPOV) or HP OpenView Operations Manager (OVO) now called HP Operations Manager, software for consolidated event and performance management, HP Network Node Manager (HP NNM) now called HP Network Node Manager i-series which has embedded run-book automation technology for automatic data collection, state verification, and problem fixing, HP Service Center formerly Peregrine, HP OpenView for Internet Services (HP OVIS) now called HP Business Availability Center, HP Reporter for OpenView and HP Operations Orchestrator (OO) formerly known as PAS, formerly IConclude

Sounds like someone changes brands like they change underwear. Nothing like re-branding an entire product line once or twice to encourage confidence from your customers.

  • Share/Bookmark

Pay the content creators

November 5, 2009

News Corp’s MySpace Google deal at risk. So, how much is your Internet traffic worth?

Google agreed in 2006 to pay News Corp $900m for the exclusive right to provide search advertising to the once-thriving site over three years if MySpace could guarantee a minimum volume of traffic.

A guaranteed minimum amount of traffic sounds like a guaranteed minimum amount of ad revenue for Google. No wonder Google is doing so well if they can consistently cut sweetheart deals like that.

Here is what Rupert needs to do if he wants to bring MySpace back to a competitive if not dominant position: Let the people creating the content share in ad revenue. The way it is now, users make the content and MySpace and Google make a fortune from people looking at it.

Content is king on the Internet. Want to improve your traffic, improve your content. Since users create the content at MySpace, it becomes essential to attract users who can consistently generate quality pop content. Even if you have to pay to get them.

A simple setup based on traffic should do it. Here is a sample:

# hits/mo     Stipend
1000          $5
10000         $50
100000         $750

MySpace could also give users the option of selling lucrative local ad blocks in addition to using pluggable ads from whatever provider they want. As with all things, free people being fairly compensated for their work is the best way to build a strong and enduring enterprise. Fall away from free enterprise principles in exchange for the easier softer way and you always get the same things: decay and tyranny, illustrated appropriately here by the MySpace Google deal.

Google is the only game in town because they have made it easy for content aggregators to make a gjillion dollars. With a little innovation and work the ad monopoly can be wrenched from Google’s iron grasp. The we’ll see how dedicated to ‘do no evil’ they are.

  • Share/Bookmark

Wordpress drill-down admin pages

October 8, 2009

I was gaining momentum on the Geocache Manager Wordpress plugin last week after solving a couple of longstanding problems with unauthenticated Ajax calls and a few Javascript quirks with Internet Explorer when yet another pesky problem surfaces. When I say pesky it means that I have been fooling around with it for several days without zeroing in on a solution, thus making zero headway on the project. To make matters worse, the problem lies with a feature that has existed from the beginning and had worked until I upgraded from Wordpress Mu 2.7 to 2.8.4a last week.

In the admin panel I have a custom top level menu with two entries: a page for the map management and a page for options. The following bit of code…

function addAdminMenu(){
	add_action('admin_menu', array(&$this, 'gcgc_plugin_menu'));
}

function gcgc_plugin_menu() {
	$gcgc_relpath  = str_replace('\\','/',dirname(__FILE__));
	$parent = $gcgc_relpath.'/gcgc-admin-form.php';
  	add_menu_page('Private Geocache Manager', 'Geocache', 1,
                                 $parent, array(&$this, 'gcgc_admin_page'));
  	add_submenu_page($parent, 'Geocache Options', 'Options', 1,
                                 'gcgc_options', array(&$this, 'gcgc_options_page'));
}

function gcgc_options_page(){
	$gcgc_relpath  = str_replace('\\','/',dirname(__FILE__));
	include($gcgc_relpath.'/gcgc-options-form.php');
}		

function gcgc_admin_page() {
	$gcgc_relpath  = str_replace('\\','/',dirname(__FILE__));
	include($gcgc_relpath.'/gcgc-admin-form.php');
}

…will give you a menu like so:
geocache-menu

That all works. The geocache admin form lists all the courses defined and for each course there is a link to load a new admin page for that course. This is basic functionality that has existed since the 1st week of development and suddenly the link no longer works. The link now generates a redirect to a sub-blog with a page not found. WTF! Where do you start at on that.

I admit I am a little weak on Wordpress redirects and I am having a difficult time understanding why the redirect would go to a sub-blog in the Wordpress Mu installation instead of the current blog. But aside from that I don’t understand why it started issuing a redirect in the first place when the code that generates the link hasn’t changed in like five months.

UPDATE: I fixed the redirect problem by deleting the sub-blogs. Now I am just getting a mangled url, like so:

http://gulfcoastgeocache.com/wp-admin/?c=1
So let's go over what I am thinking so far. I am of course using the wp-admin framework and have the faulty link set up similar to the pages accessed from the admin menu. The URL on the Geocache admin link is:
.../wp-admin/admin.php?page=private-geocache-manager/gcgc-admin-form.php
Then on that page there is an entry for each geocache course and each course has an anchor link to its own admin page, like so:
<a href=".../wp-admin/admin.php?
        page=private-geocache-manager/gcgc-admin-cache.php&id=20">
Geocache Name</a>

After checking the usual suspects — verifying paths, searching for typos, confirming no function parameters had been inadvertently changed — the only thing I can think of is that the drill-down admin page was working previously only due to a flaw in previous Wordpress. I remember when putting it in that it seemed easy. Too easy.

Over the past few days I’ve done quite a bit of searching using every term anyone could probably think of having to do with registering an admin page that is not on a menu. Compared to other development platforms out there (Make no mistake, Wordpress is a development platform) there just is not that much in-depth technical documentation outside of your standard stuff. There are many redundant articles on adding an admin menu, for example, but not much on adding a multi-page, drill-down admin system. You have to figure that out on your own. Either not many people are doing advanced development or they are very tight-lipped about their stuff.

This morning I finally came upon an article that at least verifies my thinking:

WordPress 2.8.1 contains changes to improve the security of plugins by ensuring that only correctly registered plugin pages can be accessed as well as only showing the link to the page to users who have the capability required in the add_x_page call.

The article makes no mention of dynamically created sub-pages accessed by means other than the Wordpress menu structure but down in the comments I find a fellow traveler:

I already have add_action(’admin_menu’, ‘FUNCTION’); for my main settings page. However, there’s a plugin page which is not a menu link (but an inside plugin page which is referenced when the plugin settings are saved).

And the answer to my problem, if not the solution:

You cannot just link to pages that are not registered as this would make it easy to load up files which should not be loaded so you have two choices to fix your plugin.

He goes onto say that the workaround is to use a Wordpress admin action hook or a call back to the main page to process the main form submissions.

I like to keep my pages small and manageable and this plugin will ultimately have half a dozen admin pages when all the features are added. As of now there are only three. But since I want many small files instead on one big file here is what I am going to do: I am going to create a main admin container page that includes the proper admin panel when loading based on the URL. Should have seen this problem coming and set up like this in the first place. Oh well. I’ll report back when I get the changes complete.

Read the follow-up:

Wordpress drill-down admin pages II

  • Share/Bookmark