— tomauger.com

Archive
Web Development

GDSR, in case you don’t know it, is one of the best, most complete plugins, and APIs, for adding all sorts of  ratings, thumbs and good stuff to your blog. Anyway, check it out.

Of course, like most WP stuff out there, the documentation is a mess (though I must admit this one is far better than most, so props to the dev). As I desperately try to customize the way it works, I’ll post my findings here.

Getting Admin Settings

So you want to write good code and you want to leverage the extensive settings available in the Admin panel. How to access those settings? Well I don’t know if there’s an official way or not, but digging through the many pages of PHP code, I have found

gdsr_settings_get(SETTING_NAME);

This queries the global GDSR object and grabs the setting by name. The trouble is, I haven’t found any documentation for what these settings names are. There are a couple of strategies here:

1. Query the global $gdsr object. This is a real hack, but it worked for me:

global $gdsr;
print_r ($gdsr->o);

While this ain’t pretty, you’ll get a list of every single setting available. Now you have to figure out the one you want.

2. View source on the Admin page. This didn’t work for me exactly – I had been hoping that by going to the Admin page, and inspecting one of the textfields or pull-down menus and grabbing its name or id I could find the corresponding setting. Turns out, there isn’t any direct correlation – for example the setting that controls the # of stars shown on the article page is called “gdsr_stars” where the gdsr_settings_get string is ‘stars’. Hmmm. Come to think of it, maybe they’re all related after all, just remove the gdsr_ prefix. Worth experimenting with.

That’s all the time I have. If even 1 other person finds this useful it was worth it.

Read More

Important Note: I’ve learned a ton about WordPress since this post, and it actually does not follow best practices.

I will blog on this soon (as soon as my current workload customizing WordPress lets up), but in the meantime, please see my PowerPoint presentation from my recent WordCamp Montreal talk on WordPress best practices. The post below is actually an embarassment. Maybe I should just pull it…

This is a quickie – suppose you want to quickly select the latest comments across all posts within a specific category. This mySQL query gets you there:

select C.*
from wp_comments C
join wp_posts P
	on C.comment_post_ID = P.ID
	and P.post_status = 'publish'
	and P.post_type = 'post'
 
/* join posts to category */
join wp_term_relationships TR
	on TR.object_id = P.ID
 
join wp_term_taxonomy TT
	on TT.term_taxonomy_id = TR.term_taxonomy_id
	and TT.taxonomy = 'category'
	and TT.term_id = [CATEGORY ID]
 
where C.comment_approved = 1
 
order by comment_date_gmt desc
limit 1;

Just replace the [CATEGORY ID] with your $catID and you can change the limit if you want more than just one most recent comment. Limit 5 will give you the 5 most recent comments that you can then loop through and display.

Read More

Have you discovered the <button> tag yet? It’s actually pretty cool, making it easy(er) to style submit buttons and the like to do things like, say, put pretty icons in front of the button text and so forth.

The button tag looks like this:

<button type="submit" name="action" value="delete_123">Delete This Item</button>

You can even put other cool HTML inside the button:

<button type="submit" name="submit" value="resetPwd"><span class="resetIcon">Reset Your Password</span></button>

This gives you a lot of control, which otherwise might need to be done with one or more (non-semantic) wrappers outside of an <input type=”submit” /> tag.

The real beauty (for me) of the <button> tag, is that the value that is send to your server-side (PHP, Perl whatever) can be different from the message that is displayed to the user. In the first example shown, you could imagine a list of products, each of which has a “Delete This Item” button. The User sees “Delete This Item”, but the server gets “delete_123″ and, with some very simple string splitting, can figure out what action you want it to do (delete) and what item to delete (123).

Cool.

Well, well, well, this is probably the first time I’ve seen IE break the server-side of things, but they’ve managed to cock that up too. Note that this has supposedly been addressed in IE8, but we’re not just targeting IE8 when we write RIAs are we?

The issue is that IE 6, 7 contravene the HTML 4.0 standard, and send the <button> tag’s innerHTML rather than the value!

Can you imagine that?

So what the server gets (when submitted from IE only) is:

<SPAN class=resetIcon>Reset Your Password</SPAN>

(do note that IE converts to upper case AND removes quotes from attributes as well. Awesomeness.)

All other browsers submit:

resetPwd.

Read More

Couldn’t find anything really definitive on this, so here it is. Object.hasOwnProperty() is defined by EMACS and is supposed to be present on any (and all) objects in JavaScript.

So this would (normally) make a good way to make sure that a DOM element has a certain method before calling it (particularly to be safe if the DOM object for some reason doesn’t exist as expected)

For example:

elem = document.getElementById("someDOMElement");
if (elem.hasOwnProperty("innerHTML")){
  // ... do something cool with the innerHTML of this element
}

Unfortunately, this technique fails out of hand in IE because, although native Objects do support this method, for some reason DOM objects do NOT. So it will always fail, and more likely give you the dreaded “object does not support this property or method”, which is precisely the reason you wanted to use this method in the first place!

IE can go to hell. What’s wrong with these people?

Read More

It’s been documented quite a bit on the web already: proper use of  unobtrusive JavaScript in your web pages to achieve not only behavioural separation (keeping content, style and functionality separated into HTML, CSS and JavaScript documents respectively) but also degrade gracefully, to support browsers or platforms where JavaScript is not available. These two concepts form the heart of the development ethic in New Web development:

  • Keep your HTML markup completely free of all inline styles and inline JavaScript (in essence, try to use only those attributes inside your HTML tags that are absolutely necessary
  • Do not make JavaScript a requirement to be able to access content / functionality on your sites (anticipate the user who is not using JavaScript during the browsing experience)

Using DOM traversal methods such as getElementsByTagName() and regular expressions on the class attribute, you can fairly easily parse through your markup and unobtrusively add in your behavioural JavaScript, eliminating the need to add onClick=”" or onMouseOver=”" attributes inline. However, this is all still done with JavaScript so at some point, the JavaScript code to do this unobtrusive replacement must be executed. Since it can only be executed once all the relevant DOM elements have been loaded, this has been traditionally done using the (inline) onLoad=”" attribute within the <BODY> tag.

For the purists, this represents an issue since we’re not achieving total separation. One migh argue that even putting the <script> tag in the head of the document is too tight of a coupling, but I don’t know of anyone who has cracked that chestnut yet, nor does it seem likely that we’re even going to go there.

Regardless of whether you’re that die-hard, there’s a certain elegance in letting your scripts execute themselves without any further dependencies in the HTML – you include the external .js file in your HTML’s header tag and it takes care of itself from then on. Set it and forget it.

Read More

 I don’t like wasting people’s time (what few readers I may have) with rants and raves, but I got hit in the gut twice recently by unfortunate updates.

Being the progressive guy that I am, I upgraded my Adobe Acrobat Reader software (upon ceaseless prompting by Adobe Updater) to Acrobat Reader 9. I also installed Adobe Acrobat (the full version) 8 within a short timeframe. At some point in that flurry of acrobatic upgrades, I lost my ability to display PDFs in my browser window. Explorer, Firefox, Safari, Opera – nada, zilch, bubkus, zeeero. Like so many other busy (lazy) computer professionals, I ignored it and did the Ctrl-click Save As… workaround.

Then today, after having been adamantly refusing to upgrade Firefox 2.0.0.19 to 3 (for a host of reasons – though it is installed on my web development testing laptop), I caught, out of the corner of my eye, Firefox unashamedly installing FF 3.0.5 without my consent. I cancelled, went to my prefs, ensured that “automatic updates” was OFF(!!) and happily went about my business. In due course I shut down Firefox, and later re-opened. To be greeted by the message “Firefox is installing updates.” And that was all there was to it. No choice in the matter – bend over this won’t hurt a bit. Of course that meant that my plugins stopped working (what would I do without Firebug??) and since then Firefox has been crashing like Amtrak in winter. Thanks.

So naturally, the next time I was trying to open up a PDF in a browser and got the friendly error message to the effect of “error – The Adobe Acrobat/Reader that is running can not be used to view PDF files in a Web Browser. Please exit Adobe Acrobat/Reader and try again.” I LOOOOOSE it. I grabbed my computer in a figure 4 headlock, deaked it out with a headfake to the GPU and slammed an uppercut right up the USB.  “Is that ‘can not be used to view PDF files in a Web Browser’ enough for ya?” I gloated.

Solutions, Tom, not problems please. This is a constructive blog.

Right. So, after reassembling my GPU and rubbing some vaseline on my USB ports, I did some research. Many complains, some very bizarrre solutions (from Adobe) involving clearing out some registry keys, everything quite suspect. The most promising option was to open the Reader Software, go to Preferences > Internet and make sure “View in browser” was turned on. It was – so I turned it off, quit the app, relaunched, turned it on and tried again. Nothing. Not even re-loading the browser solved it.

So I uninstalled, and re-installed Acrobat 8. I found a very helpful Adobe Acrobat 8 standalone installer which has worked without a hitch. So until Adobe gets their act together (I’m completely flabbergasted that their Acrobat 9 for Windows is so crippled and hasn’t been fixed yet), do yourself the favour and do not upgrade. If you have, and are experiencing the same issues, do uninstall Acrobat 9 and then install Reader 8.

Happy surfing!

Read More

Well, I’ve been delinquent again with my regular posts here. Partially because I’m starting a new blog over at blog.zeitguys.com along with my other co-conspirators. But that’s no excuse.

Partially due to the encouragement of people who’ve stumbled upon some of my other tips and tricks, here’s a quickie that had me stumped for quite some time. I hope it’s of help.

The Issue:

When styling a SELECT tag using CSS and increasing the font size, in Explorer (7) the visual display area of the drop-down menu increases correspondingly. In Firefox, the form SELECT tag does not scale correctly – it cuts off some of the text. The larger the font size, the more the text gets cut off. This is the case regardless of whether you’re using pixels, points or ems. Line-height also has no bearing on it.

It turns out after some experimentation, and a completely random Google hit to some obscure Java CSS reference pages that gave me the idea, that in Firefox you also need to set the same font size in your OPTION tags.

So…

select, option {
	font-size:1.4em;
}

Will do the trick…

So remember, if you’re setting font-size in a SELECT tag, set the same font-size in your OPTIONs as well (unless you’re using a fixed width for the tag, in which case it doesn’t matter).

Read More

So I came across the most baffling bug the other day that locked me up for a good three hours. I thought maybe I’d just put down what I discovered here on the outer reaches of the blogosphere in case anyone else happens to hit that magical combination of Google keywords and a link to this page comes up.

To describe the problem succinctly: when you’re trying to create a horizontal menu using unordered lists (<ul> and inline <li>), for some reason, in Firefox (2 – I don’t know about 3 which just came out last week), if there is any whitespace between a closing </li> tag and the opening <li> tag of the next item, that whitespace actually displays. At first it looks like a margin spacing issue, but after some tests it’s clearly not. In fact, what baffles me is that ANY text between the closing </li> and the opening <li>, that text actually gets displayed inline! Which makes no sense, because I didn’t think that the <ul> element could have a text node as a direct child. Apparently it can, in Firefox at any rate.

The solution, as I have discovered is to set your <ul>’s display attribute to “table”. I don’t believe IE7 and certainly not IE6 understand display:table, so this is a non-IE fix, but then again, IE wasn’t exhibiting the whitespace behaviour. Here’s some sample code.

 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
	"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Untitled Document</title>
<style type="text/css">
    *    { margin:0; padding:0; }
    ul {
        list-style-type:none;
        list-style-position:inside;
        margin:0px; padding:0px;
        display:table; /* This is used for firefox */
	/* to avoid the horizontal whitespace bug */
    }

    li {
        border:1px solid black;
        display:inline;
        margin:0px; padding:0px;
        border-collapse:collapse;
    }

    a {

    }

</style>

</head>
<body>
    <ul>
        <li><a href="#">Line 1</a></li>
        <li><a href="#">Line 2</a></li>
        <li><a href="#">Line 3</a></li>
    </ul>
    <p>Other stuff....</p>
</body>
</html>
Read More

So here’s a real doozie that came from a question someone asked on ExpertsExchange: he had two separate Flash Projectors (EXEs) – that needed to be able to intercommunicate (the first projector needed to know when the second projector had actually finished loading). Since we’re dealing with external projector files that have no dependencies (rather than using the movieClipLoader to load an external SWF into the parent movie), the only thing I could think of that would work reliably was local SharedObjects.

As I put together a solution for this brave soul, I encountered a few interesting challenges, and a few frustrations. Thought I’d document it here because I couldn’t find anyone else who had addresses the intricacies of having two SWF share a SharedObject and monitor the status of that shared SharedObject so they could respond to a change in status.

Here’s the basic principle:

  • Application 1 creates a local SharedObject and sets an initial status
  • Application 1 also registers an enterFrame event listener that listens for a status change on the SO
  • Application 2 accesses the same SO and at some point, changes the status
  • Application 1′s enterFrame handler detects the status change, and responds to the event.

As I write this, I see there’s an opportunity for a custom event class that does all this, but I’m going to leave that to the real gurus. I don’t pretend to have that intimate a knowledge of ActionScript to be able to pull that off. I should also point out at this time that the original EE user’s question was for AS2, so this solution is only tested in AS2, though since the issues I was running into were related to variable scope, I would only imaging that an AS3 implementation would be easier, if anything.

Here are the challenges I encountered:

  • how to launch one EXE Projector from another EXE Projector
  • how to share a SharedObject between two Flash movies (SWFs)
  • how to continuously monitor the value of a shared SharedObject
Read More

This was a question I answered recently on experts-exchange, and, considering the verbosity of it all, I thought I’d capture it for anyone that might find it useful.

 The poster wanted to create a popup window using HTML and JavaScript that would open when the page first loaded, but then, if the user navigates away from that page, and then came back, would not bother them by popping up again.

 Here’s the solution:

The command for a popup window is:
window.open();

To make the window open when the user first comes to your page, you put the popup in the HTML <body> tag like this:

<body onLoad=”window.open();”>

There are some additional parameters you can pass to window.open() to do things like set the name, the size etc.

If you want to make sure the popup only happens once per session for a user (so it doesn’t pop up every time) you need to set a session cookie.

The session cookie is stored on the person’s computer and is erased once they close their browser window. This is useful for making sure that the NEXT time they visit the site, they will see the popup again.

If you don’t want the user to ever see the popup again after the first time, use a regular cookie that doesn’t expire, or expires in a very long time.

These are some excellent tutorials on setting and reading cookies. You’ll have to brush up on your JavaScript skills a little.

http://www.quirksmode.org/js/cookies.html
http://www.w3schools.com/js/js_cookies.asp

For a general tutorial on JavaScript, check these guys out:
http://www.w3schools.com/js/default.asp

Here are all the parameters you can pass to window.open to do all sorts of neat things with the popup window. This page is a little technical, so maybe wait until you’ve got a basic window working before trying to tweak the popup window with help from this link:
http://www.w3schools.com/htmldom/met_win_open.asp

Cookies will probably be the hardest part for you to implement. So I’m just going to copy and paste some code here, straight out of the w3schools tutorial, with a bit of explanation and some specific code for you:

first, in the <head> of your HTML page, start with your <script> tag:

<script type=”text/javascript” language=”JavaScript”>
// the rest will go inside here (see below)

</script>

Okay, now, copy and paste the following functions into the area we’ve left for the Script tags.

function mySetCookie(c_name,value,expiredays)
{var exdate=new Date()exdate.setDate(exdate.getDate()+expiredays)
document.cookie=c_name+ “=” +escape(value)+
((expiredays==null) ? “” : “;expires=”+exdate.toGMTString())
}

function myGetCookie(c_name)
{
if (document.cookie.length>0)
  {
  c_start=document.cookie.indexOf(c_name + “=”)
  if (c_start!=-1)
    {
    c_start=c_start + c_name.length+1
    c_end=document.cookie.indexOf(“;”,c_start)
    if (c_end==-1) c_end=document.cookie.length
    return unescape(document.cookie.substring(c_start,c_end))
    }
  }
return “”
}

// —————————————-

Okay, those are the functions we’ll use to set and retrieve the cookie to see if the user has already seen the popup window.

Now here’s the custom code that you’ll put after the code you just copied and pasted (still inside the SCRIPT tags). We want to check if the user has already got a cookie. If so, it means the user has already been to this page and (presumably) seen the popup already, so we don’t display it again. Otherwise, we display it.

function showPopupOnce() {
   var hasSeenPopup = myGetCookie(“has_seen_popup”);
  if (hasSeenPopup == null || hasSeenPopup == “”){
     // the user has never seen the popup, so show him!
    window.open(“http://mywebsite.com/popup.html“, “myPopupWindow”);
   }

   // either way, set the cookie so the user will never see the window again
   mySetCookie(“has_seen_popup”, “true”, 365); // 365 days = 1 year
}

// ——————————

Okay, great, now the only thing to do is make sure that the showPopupOnce() function runs whenever the page loads. Go into the <body> tag and change it to this:
<body onLoad=”showPopupOnce();”>

That should do the trick.

Tom

Read More