WordPress – 301 location to sub page

WordPress is great for blogging but still has a way to go to be a CMS. One thing I find odd is that you can create Categories for Posts but not for Pages. Usually a client will want pages categorized for navigation. So this becomes a problem. Sure you can nest Pages (parents and children) but that means you must have content in every menu item.

After a quick google search I came across some code that allows WP’s Pages to have empty menu items for categorization. Or at least that’s the visual effect. The fix is to create a Template in your theme with some PHP code. It redirects the browser to the first Child Page:

<?php
/*
Template Name: Redirect To First Child
*/
if (have_posts()) {
  while (have_posts()) {
  the_post();
  $pagekids = get_pages("child_of=".$post->ID."&sort_column=menu_order");
  $firstchild = $pagekids[0];
  wp_redirect(get_permalink($firstchild->ID));
 }
}
?>

This works but I’m not too fond of it. It uses a refresh. I tweaked it a bit. Changed the wp_redirect to a Location header and added a 301 status code:

<?php
/*
Template Name: 301 Redirect To First Child
*/
if (have_posts()) {
 while (have_posts()) {
  the_post();
  $pagekids = get_pages("child_of=".$post->ID."&sort_column=menu_order");
  $firstchild = $pagekids[0];
  header("HTTP/1.1 301 Moved Permanently");
  header("Location: ".get_permalink($firstchild->ID));
  exit();
 }
}
?>

This is much faster on the front end. It also tells search engines not to index those blank categorization pages.

<?php/*Template Name: 301 Redirect To First Child*/if (have_posts()) {  while (have_posts()) {    the_post();    $pagekids = get_pages(“child_of=”.$post->ID.”&sort_column=menu_order”);    $firstchild = $pagekids[0];   header(“HTTP/1.1 301 Moved Permanently”);   header(“Location: “.get_permalink($firstchild->ID));   exit();  }}?>

Updated compressed scripty 1.8.3 for LightView, PHP

I ran across a problem with LightView which is stated as requiring Prototype 1.6.1 and Scriptaculous 1.8.2. Yet it was failing even when I had scriptaculous 1.8.3 loaded.

Apparently LightView looks for the loader scriptaculous.js rather than the actual components (effect, builder, etc).

My previous compressed Prototype 1.6.1 and Scriptaculous 1.8.3 did not have the loader/stub scriptaculous.js file. Ideally, that’s never needed as long as you load the other scriptaculous js files.

So here is an updated package. Also in this archive is the PHP version of the ColdFusion file to server the jgz.

The combined file is now 273KB. The load order is as follows:

  • prototype
  • scriptaculous
  • builder
  • effects
  • dragdrop
  • controls
  • slider
  • sound

It includes all comments and credits. I gzipped it down to 62KB.

You’d load it like so:

<script type="text/javascript" charset="ISO-8859-1" src="/includes/js/scriptaculous/scriptaculous.cfm"></script>

Download it: wv-scripty-183.zip

Custom scrollbars in Adium – ‘Elegant Simple’ Message Style

Visually based on the “Pretty Simple” Message Style by Piotrek Marciniak, I’ve created a new breed of Adium Message Style – which boasts a completely custom scrollbar.

This message style is a working proof of concept. It is a prototype for the talented folks that create  wonderful message styles. I’m a developer, not an artist. I hope that others will use it as a spring board for rapid development of a whole new breed of message styles with custom scrollbars.

Since Adium Message Styles are really web pages, it only seemed right to mash up Prototype JS, LivePipe UI and Scriptaculous!

Features

  • Fade-in of messages
  • Auto smooth scrolling when new message is received
  • Custom styled scrollbar
  • Dynamic height scrollbar handle
  • Header and Footer objects of scrollbar handle
  • Auto-hiding and fading scrollbar (mouse in/out of window)
  • Mouse wheel support

[media id=11 width=600 height=470]

( View full size 800×600 MP4 3.7MB )

Go and get it!

Visual Code Editor 1.2.5

I’ve updated Visual Code Editor. Not so much an upgrade, but tested it out with SyntaxHighlighter Evolved 2.3.8 and WordPress 2.9.2.

SyntaxHighlighter Evolved fixes a lot of the problems that VCE also fixed (for SyntaxHighlighter Plus 1.x). But VCE still comes into play when you want to use tinyMCE (the post editor) in WordPress.

  • Adds `<pre>` & `<code>` to block format menu
  • Allows extra attributes for compatibility in some syntax highlighters (ie, `<pre lang=”php” line=’5′>`)
  • Unescape WP’s double escaping of & (not needed with SHE)
  • Allows iFrames in the post
  • Support for syntax highlighting in comments
  • Removes extra `<pre>` tags around SyntaxHighllighter Plus’s sourcecode blocks

I tested it out with SHE and they both play very well together. Although the fixes in VCE are no longer needed, it still adds some functionality to the Visual Editor. Since nothing broke, I’m not going to fix it (remove the fixes). This allows its continued use in other client side syntax highlighters.

Go get it –> http://wordpress.org/extend/plugins/visual-code-editor/

Also, I highly recommend SyntaxHighlighter Evolved.

Compressed Prototype 1.6.1 and Scriptaculous 1.8.3

I created a new compressed file for Prototype 1.6.1 and Scriptaculous 1.8.3. Included is my modified sound.js.

The combined file is 268KB. The load order is as follows:

  • prototype
  • builder
  • effects
  • dragdrop
  • controls
  • slider
  • sound

It includes all comments and credits. I gzipped it down to 60KB.

For your convenience in the attached zip contains both versions and a ColdFusion file to serve the correct one. You’d load it like so:

<script type="text/javascript" charset="ISO-8859-1" src="/includes/js/scriptaculous/scriptaculous.cfm"></script>

Well, what are you waiting for? 🙂 wv-scripty-183.zip

Speeding up cffm v1.1x

I manage a site with nearly 50GB of small PDFs. Thousands of directories and files. This makes CFFM super duper slow. I know it sounds silly, but when staring at a blank window, 15 seconds feels like 15 minutes. The problem is that with every page load, the entire directory tree below your initial directory is read. Crazy. Here is the fix…

At around line 648 of cffm.cfm, only turn on recursion if this particular action requires it:

<cfset variables.listAllFiles = cffm.directoryList(cffm.includeDir, (isdefined("url.action") and url.action eq 'copymoveForm'))>

… which is, when moving or copying. In my application, speed increased 10x.
And to get a little more speed when listing a directory with images…

At around line 67 of cffm.cfm, turn off image sizes:

<cfinvokeargument name="enableImageDimensionsInDirList" value="true">

CFSelect with multiple query columns

CFSelect is nice because it can help you write out some code quicker. Just like the rest of ColdFusion. But I never used it because so many times I needed to display two columns in the <option>, such as “#lastName#, #firstName#”.

While working on a site I fell into the same routine. I start typing out CFSelect then grit my teeth when I get to the Display attribute. Being stubborn about it I stumbled upon a nice MySQL function called CONCAT(). Using that one can merge two columns in the query to be output as a single column name. Like so:

<cfquery name="emps" datasource="#application.datasource#">
SELECT
 id, CONCAT(lastname, ', ', firstname) AS fullName
FROM
 employees
ORDER BY
 lastname, firstname
</cfquery>

Then simply use that column name for the display (or elsewhere needed):

<cfselect name="employeeid" query="emps" selected="" value="id" display="fullName"/>

I’m a Favorite Place on Google

I received a nice treat in the mail recently. A Happy-Winter-Solstice card from Google? Sorta. The envelope was somewhat big and said Congratulations on it. I would have tossed it if it was not from Google. I opened it and, lo and behold, it’s a window sticker stating I’m a Favorite Place on Google. How cool! And I’ve never even heard of that.

were-a-favorite-place-on-google

So I quickly stuck that bad boy sticker in my ‘office’ window. Keep in mind that I work from home. There was a board meeting the next morning, and the outcome was the sticker came down very shortly thereafter. I think it was up for maybe 8 hours at best that night. =)

What am I Favorite Place for? Why, “web development“, of course!

Apparently local businesses are supposed to put this sticker in their window. Then yuppies snap pics of the barcode with their cell toys to get instant information about the business. I donno… why not just go in and say hi?

Less than 1% of businesses get these. So I’m pretty psyched. The other board members are… bored members.

The list was determined based on the popularity of a business’ Local Business Center listing, as determined by how many times Google users looked for more information about a business, requested driving directions to get there, and more. Google users “decided” based on their actions, and we sent the decals.

Over 100,000 businesses were identified as Favorite Places, representing less than 1% of the 28 million U.S. businesses. We believe that our standards for selecting businesses are as selective or more selective than other companies which have run similar initiatives.

http://www.google.com/help/maps/favoriteplaces/business/faq.html

MySQL: counts of multiple sub-items of each parent

Sometimes it is useful to show in a list the numbers of children each object has. For instance how many Products are in each Category.

That’s simple enough to do when only one child type is used:

SELECT
 categories.title, categories.id,
 count(products.id) as productCount
FROM
 categories
   INNER JOIN products ON categories.id = products.categoryid

However, if you wanted to count two separate children types, the same method of querying will give you very odd results:

SELECT
 categories.title, categories.id,
 count(products.id) as productCount, count(images.id) as imagesCount
FROM
 categories
   INNER JOIN products ON categories.id = products.categoryid
   INNER JOIN images ON categories.id = images.categoryid

The lazy programmer would get around this by using the server language – looping through a simple query of the category, and with each row run another query to count the products (and another for the images). Yuck.

Instead, I found this method to work quite well:

SELECT
 cats.title AS title, cats.ID AS id,
 COALESCE(prods.howmany,0) AS productCount,
 COALESCE(imgs.howmany,0) AS imageCount
FROM (
 SELECT title, ID
 FROM categories
) AS cats
LEFT JOIN (
 SELECT
   count(products.id) as howmany,
   products.categoryid as categoryid
 FROM products
   LEFT JOIN categories ON products.categoryid = categories.id
 GROUP BY products.categoryid
) AS prods ON cats.id=prods.categoryid
LEFT JOIN (
 SELECT
   count(images.id) as howmany,
   images.categoryid as categoryid
 FROM images
   LEFT JOIN categories ON images.categoryid = categories.id
 GROUP BY images.categoryid
) AS imgs ON cats.id=imgs.categoryid

Note the use of the ‘COALESCE()’ function so that nulls are returned as a 0 (zero).
As you can see the database is still running three queries. But they are all within one connection, and the server language didn’t do any work.  Then MySQL joins those queries together into one result, easily parsed by your server language of choice. Here, ColdFusion:

<table>
 <tr>
   <td>Category</td>
   <td>Products</td>
   <td>Images</td>
 </tr>
 <cfoutput query="read">
 <tr>
   <td>#title#</td>
   <td>#productCount#</td>
   <td>#imageCount#</td>
 </tr>
 </cfoutput>
</table>

Making Apple’s DigitalColor Meter useful

DigitalColorMeter
I had a long time gripe about the DigitalColor Meter that ships with Mac OS X. It would be nice to use it for web development when you want to copy a color from an image to make text of the same color with CSS. But the way this utility works drove me nuts…

Setting the pulldown to “RGB as Hex Value, 8-bit” sounds right. Then put the aperture over the color you want, hit command+shift+c and you have the hex rgb in your clipboard. Nice! So go paste that into your css editor and you get:

Note the quotes
Note the quotes

So now I have to go in and remove the quotes manually each time. But then, it still does not work when you view the web page. Turning on hidden characters reveals…

What a mess
What a mess

“… just… like… WHY, Steve?” An otherwise nice utility is a real pain to do anything useful with.

Well, tonight I found a good workaround for this. In the preferences, turn on “Drag in swatch drags out the color”:
Picture 5 Then, Instead of command+shift+c, do a command+shift+h. That holds the color instead of copying it:

Picture 4 Then drag that chip in the middle to where you want to copy the hex…

Picture 8

And there you have it:

Picture 7

Now… as to why it is holding F39200 but dragged F88D00? I have no idea! Comments, suggestions, etc are welcome.