Marc Blase

Adaptive Images

Interesting take on adaptive images for responsive design web sites.

Published on June 28, 2012

IMAP copy

I have a client that recently wanted to move onto their own hosting account. Web files were no problem, tar and gzip’d their directory’s contents in one shell window, wget’d in another, decompressed files. Done. Dump database from one phpmyadmin window, then import into another. Done. This was the easy part.

Hard part was they also wanted to move their entire email configuration. These clients are very organized, which means that there are lots of nested IMAP folders. Tried a few tools out but they either timed out, couldn’t authenticate src and dest in a single connection, or didn’t read recursively into the folder structure. Finally found IMAPcopy, a project that hasn’t had an update in six years and was still alive on the interwebs. And guess what? It worked.

Download linux binary here and source here. In case the original project page ever goes down, I have it saved here for posterity’s sake.

Since my clients are so organized they nested folders without any messages in either the parent, grandparent or great-grandparent folders. Great for organization, not so much in looking for messages, so the program skipped the first one that didn’t contain a message even if the rest of that branch contained messages. So, I simply needed to run the program, once configured with a “-e” flag, which included empty folders in its operation. Sweet!

Client keeps highly organized IMAP folders and I learned something new.

UPDATE 2018-05-08:

To simplify this whole process I now use imapsync from the command line. So just apt-get install imapsync or dnf install imapsync depending on your distro.

UPDATE 2020-01-24:

To simplify this whole process even further I recommend mbsync. I switched hosts so this made transferring multiple mailbox accounts less painful since it allows config via a file.

Published on June 14, 2012

Removing those bothersome Facebook Canvas app scrollbars

Just did my first app since Facebook has forced timeline on everyone.

PROS: Full width page tabs.

CONS: Can’t make the page open on a page tab (AFAIK). Scrollbars if your page tab markup extends to 810px.

To fix the scrollbar issue you have to load the FB SDK and make a call to the FB.Canvas.setAutoGrow() function. This will push the iframe to the bounds of your markup, which if sized correctly, will make the scrollbars disappear.

Here’s the code:

<div id="fb-root"></div>
<script>
  window.fbAsyncInit = function() {
    FB.init({
      appId      : 'YOUR_APP_ID', // App ID
      channelUrl : 'YOUR_APP_URL/channel.php', // Channel File
      status     : true, // check login status
      cookie     : true, // enable cookies to allow the server to access the session
      xfbml      : true  // parse XFBML
    });

    // Additional initialization code here
	// FB.Canvas.setAutoResize();
    FB.Canvas.setAutoGrow();
  };

  // Load the SDK Asynchronously
  (function(d){
     var js, id = 'facebook-jssdk'; if (d.getElementById(id)) {return;}
     js = d.createElement('script'); js.id = id; js.async = true;
     js.src = "//connect.facebook.net/en_US/all.js";
     d.getElementsByTagName('head')[0].appendChild(js);
   }(document));
</script>

Include the code above just after the opening body tag. You’ll also need to setup a channel file, as referenced in the code above via the “channelUrl” option. According to the FB docs you want this to cache and it’s very important that the protocols match, so make them protocol independent. Eg. “//www.website.com/channel.php”.

Here’s the code for the channel file:

 <?php
 $cache_expire = 60*60*24*365;
 header("Pragma: public");
 header("Cache-Control: max-age=".$cache_expire);
 header('Expires: ' . gmdate('D, d M Y H:i:s', time()+$cache_expire) . ' GMT');
 ?>
 <script src="//connect.facebook.net/en_US/all.js"></script>

Also include overflow:hidden; in your CSS for the body tag so that there is no flash of scroll bars while we are waiting for things to happen when the page loads.

Reference: Facebook JavaScript SDK

Published on June 12, 2012

When it all began

When it all began: 173370780

Published on May 16, 2012

DD-WRT Internal Routing Hack/Fix/Mod

This hack/repair is well documented in the DD-WRT Forums but I’m including it here so I can easily find it for future reference.

I’m pointing a subdomain back to my local network which resolves to a server running apache. This works great outside the network, but internally … no dice. So the following rule needs to be applied to get things working:

Save the following commands to the Firewall Script on the Administration->Commands page to fix loopback.

insmod ipt_mark 
insmod xt_mark 
iptables -t mangle -A PREROUTING -i ! `get_wanface` -d `nvram get wan_ipaddr` -j MARK --set-mark 0xd001 
iptables -t nat -A POSTROUTING -m mark --mark 0xd001 -j MASQUERADE 

UPDATE: NAT loopback is once again working since build 19969. This fix should only be needed for builds between 15760-19969.

Published on May 14, 2012

Yeah, what he said.

Principles of User Interface Design

Published on May 7, 2012

Stop WordPress from wrapping <img> up with <p>

Img: “WordPress, why you wanna wrap me up?”

WordPress: “You looked cold.”

Img: “Well I’m not.”

WordPress: “Oh.”

Here’s how to stop that from happening:

// stop wordpress from wrapping images in <p> tags
function filter_ptags_on_images($content) {
    // do a regular expression replace...
    // find all p tags that have just
    // <p>maybe some white space<img all stuff up to /> then maybe whitespace </p>
    // replace it with just the image tag...
    return preg_replace('/<p>\s*(<a .*>)?\s*(<img .* \/>)\s*(<\/a>)?\s*<\/p>/iU', '\1\2\3', $content);
}
// we want it to be run after the autop stuff... 10 is default.
add_filter('the_content', 'filter_ptags_on_images');
Published on April 20, 2012

Remove Widget from WP Sidebar

add_filter('sidebars_widgets', 'hidemywidget');
function hidemywidget($all_widgets) {
    // Uncomment to get access to the identifiers we are trying to target
    //echo "<pre>";
    //print_r($all_widgets);
    //echo "</pre>";
    //comment the following out and see what happens!
    //return $all_widgets;
    //this should run on the homepage / frontpage only! you can use more conditions here
    if( is_front_page() || is_page() ){
		// match to your registered sidebar widget!!!
        foreach ($all_widgets['sidebar-1'] as $i => $inst){
            //check if the id for the widget to extract exists.
            $pos = strpos($inst, 'categories');
 
            if($pos !== false)
            {
                //remove the archives widget by unsetting it's id
                unset($all_widgets['sidebar-1'][$i]);
            }
        }
    }
//comment the following out and see what happens!
return $all_widgets;
}

To do: Target an array of widgets to exclude. Rewrite function to pass vars as arguments of function.

Published on April 13, 2012

Thanks for the inspiration

Finding Success as a Web Developer

Published on April 6, 2012

Force (some) MIME types to download

OK, so technology is hard for some people. Really it is. So, I think we should make things easier on them by forcing certain MIME types to download to their computer. I know, you’re probably about to say, “but what about tablets and smart phones?” Well, we’re talking about simplification here and if these people even thought about that, their brains would explode. So, here’s the goods. Fire up your trusty text editor and add this to your site’s .htaccess file:

<filesmatch "\.(?i:doc|odf|pdf|rtf|txt)$">
      ForceType application/octet-stream
      Header set Content-Disposition attachment
</filesmatch>
Published on March 30, 2012