web technology is a way of life
12 Jan
Based on an earlier post about short URL issues I decided to update my blog to support it’s own short URL using the wordpress post ID. So now any post on my site can be referenced via a shortURL, this one in fact is http://joelnagy.com/p176.
In order for this to work I added this line to my .htaccess file in the root of my site to set it to redirect the short URL to the actual page (you need the full domain in the rule since WordPress works based on the REQUEST_URI) :
RewriteRule ^/?p(\d+).*$ http://example.com/?p=$1 [QSA,L]
This code is for use in header.php to create the <link> tags that will identify your page’s shorturl. First at the top of the page:
<?php
$this_ID = this_ID();
$shortlinkid = ($this_ID != ''? $this_ID: (isset($_REQUEST['p']) && $_REQUEST['p'] != ''? $_REQUEST['p']: ''));
$uri = $_SERVER['REQUEST_URI'];
if ($uri != '/blog/' && $shortlinkid != '')
$shortlinkid = "/p{$shortlinkid}";
else if ($uri != '/blog/')
$shortlinkid = $uri;
header("Link: <http://example.com{$shortlinkid}>; rel=\"shortlink\"");
?>
Then inside the <head> (near other <link>s):
<link rel="shorturl" href="http://example.com/<?php echo $shortlinkid; ?>" />
<link rel="shortlink" type="text/html" href="http://example.com/<?php echo $shortlinkid; ?>" />
<link rev="canonical" rel="self alternate shorter shorturl shortlink" href="http://example.com/<?php echo $shortlinkid; ?>" />
Here is the this_ID() function that needs to be added to functions.php:
function this_ID($force = false) {
global $wp_query;
if (count($wp_query->posts) == 1 || $force)
return $wp_query->post->ID;
return '';
}
You can also add this code for tweeting the short URL (via chuchcrunch.com):
<!-- This is a link to tweet the post using the new short URL -->
<a rel="nofollow" target="_blank" href="http://twitter.com/home/?status=Just Read : <?php the_title();?> : http://example.com/p<?php the_ID(); ?>">Tweet This Post!</a>
4 Jun
There’s a basic issue with placing floating <div>s or any floating element for that matter in a parent <div>, the parent looses all sense of height and becomes essentially invisible. The parent can now no longer have a background, border or any defining style that would show up behind and around the children elements. But with a bit of CSS you can remedy that situation. Look at how the Example After heading is pushed around because the <div> isn’t cooperating nicely.
HTML:
<div id="Footer">
<a href="/blog/">Home</a>
<a href="/blog/contact/">Contact</a>
</div>
CSS:
#Footer {
background: yellow;
border: 1px solid blue;
}
#Footer A {
float: left;
width: 100px;
}
#Footer:after {
content: "";
display: block;
height: 100%;
clear: both;
}
Example Before:
Example After:
14 May
Just found my self needing to implement an <iframe> into a MODx site, and since I wanted to have the <iframe> be part of the template I felt it would be best to have the src, width and height be template variables making the <iframe>’s appearance based on the content and not fixed. For my particular needs I was wrapping everything in a <table> that then needed to have a width slightly larger than the <iframe>. For this I came up with a simple snippet that evals a little equation forcing it to an integer to be safe:
<?php
// eg: [[math?math=[*iframeWidth*]+34]]
if (isset($math)) {
eval("\$math = (int) ". $math .";");
echo $math;
} else
echo "0";
?>
So if [*iframeWidth*] is set to 550 and I have <table width=”[[math?math=[*iframeWidth*]+34]]“> in the template then the rendered HTML will be <table width=”584“>
23 Mar
For a few years now I’ve relied on zoom: 100% as my saving grace for finding lost elements in Internet Explorer. You see sometimes when you try to position an element on the screen, place a transparent <div> over a Flash object, or do something slighly out of the ordinary, IE will freak out and not display the object, hide it, or drop it to the bottom of z-index order.
Fortunately there’s a solution in the form of a hack called Zoom. Zoom is a CSS style that allows IE to zoom in on an element. Typically you don’t need to do this, and oddly enough when you do apply zoom even at the non-zoomed level of 100% it forces Internet Explorer to re-evaluate it’s CSS styling. So now you can make sure that these lost elements come back to where they are supposed to be.
So when in doubt, use zoom.
<!--[if IE]>
<style type="text/css">
#element{
zoom: 100%;
}
</style>
<![endif]-->
11 Mar
Here’s a jQuery object creation tip for a problem that I just ran into while coding:
This code works fine in Firefox 3, but not in IE 7:
jQuery(document.body).prepend('<div id="A"></div>');
var $A = jQuery('A');
alert($A.attr('id')); // undefined
So instead use the .prependTo function to instantly get the newly created object:
var $B = jQuery('<div id="B"></div>')
.prependTo(jQuery(document.body));
alert($B.attr('id')); // B
It is also cleaner looking.
3 Mar
Building off my previous entry Posting to WordPress via BlackBerry I’ve updated my wp-mail.php script to work with twitter_updater. It’s not the best solution but it works for now.
require_once(ABSPATH.'/wp-content/plugins/twitter_updater/twitter_updater.php');
do_action('publish_phone', $post_ID); // current update to WP
if (function_exists(vc_doTwitterAPIPost)) { // if twitter_updated exists: update
$twitterURI = "/statuses/update.xml";
$twit = $post_title . ' ( ' . get_permalink($post_ID) . ' )';
$sendToTwitter = vc_doTwitterAPIPost('status='. $twit, $twitterURI);
echo "\n<p>" . sprintf(__('<strong>Twitter:</strong> %s : %s'), $sendToTwitter, wp_specialchars($post_title)) . '</p>';
}
I also made some other updates to compensate for some changes to my email system which now base64 encodes part of the message. Here I added this code to split at the “base64″ marker instead or “quoted-printable” marker:
if (strpos($content, "Content-Transfer-Encoding: base64") !== false) {
$content = explode('Content-Transfer-Encoding: base64', $content);
$base64 = true;
}
$content = $content[1];
if ($base64) $content = base64_decode($content);
27 Feb
I’ve found a little problem with MODx and transferring data to a snippet and using it in a string comparison. The issue arises when you call a snippet from within a page (in the [*content*] portion). There is also an issue when passing a MODx var in a snippet parameter. In order to overcome this issue, I’ve needed to create two snippets, one called within the template and another that can be called in the text of [*content*] and get the data from the first snippet.
1. Create a snippet called [[setup]] with this code:
$modx-vars = Array();
$modx->vars['alias'] = $alias;
2. Create another snippet called [[nav]] which would have code like this that would give a class to a navigation link for example:
$alias = $modx->vars['alias'];
echo $alias == 'index'? ' class="current"': '';
3. Then we’ll need a template with this code:
[[setup?alias=[*alias*]&done]]
[*content*]
Note: In the call to [[setup]] we end with &done since the triple end brackets ] cause a problem of their own.
4. Finally create a page with this content:
[[nav]]
Now you can use the $modx->vars array to pass any data you need from one snippet to others when you need to use that data for actual string comparison, manipulation or usage that would otherwise only be accessible after MODx performs a php eval.
6 Feb
Yesterday, I posted my first post via BlackBerry after dealing with a few issues in WordPress that required a little modification to the wp-mail.php file. Seems that HTML emails don’t get through very well. So here are two basic steps to posting via email with your BlackBerry.
Set up your BlackBerry user account as an Author. From the Dashboard, go to Users and add the email account you use on your Blackberry, your name and a different login and password (you won’t really need these as this account is for email posting) and the Role to Author. Optionally, after you save go back to the new user and set the Display name as your name, so all posts look the same.
Now overwrite your wp-mail.php file with this one.
Here’s the code I changed:
if ($content_type == 'multipart/alternative') {
$content = explode('--'.$boundary, $content);
$content = $content[2];
$content = explode('Content-Transfer-Encoding: quoted-printable', $content);
// BlackBerry Conversion Code
$content = $content[0];
$BODY = strpos($content, '<BODY>');
if ($BODY !== false && $BODY > 0 && $body === false) $content = substr($content, $BODY);
$patterns = array ( '/<FONT FACE\=3D\"Verdana, Helvetica, Arial\"><SPAN STYLE\=3D\'font-size\:12\.0px\'>/',
'/<\/SPAN><\/FONT>/',
'/\=[\n\r]+/',
'/<BODY>[\n\r]+/',
'/<\/BODY>[\n\r]+/',
'/<HTML>[\n\r]+/',
'/<\/HTML>[\n\r]+/',
'/<BR>/');
$replace = array ('', '', '', '', '', '', '', '<br />');
$content = preg_replace($patterns, $replace, $content) . '</p>'; // replace and add trailing P tag
$content = strip_tags($content, '<img><p><br><i><b><u><em><strong><strike><span><div>');
} else if (stripos($content_transfer_encoding, 'quoted-printable') !== false) {
$content = quoted_printable_decode($content);
}
$content = trim($content);
Try it out, let me know if you have any issues.
26 Sep
I’ve always found that it is easier to drop the query string into an object similar to the $_GET object in PHP. This allows you to grab any query variable by it’s name by simply calling window.query.name or window.query['name'] as well as getting the number of query vars available via window.query.length to simply check if any exist. For the hash, I like to use it as a breadcrumb style path separated by slashes, so here I’ve split it into an array that can be accessed via window.hash[2] and accurately report the number of parts with window.hash.length that reports an empty ‘#’ as 0.
// Query | Hash Globals
window.query = new Object();
window.hash = new Array();
// Populate Query String Object, iterate over each name-value pair
window.query.length = 0;
window.location.search.replace(
new RegExp('([^?=&]+)=([^&]*)?', 'g'),
// populate the object with the values by name
function($0, $1, $2) { window.query[$1] = $2; window.query.length++; }
);
// Split the hash into sections by / or any other char
window.hash = window.location.hash.slice(1).split('/');
window.hash.length = window.hash.length == 1 && window.hash[0] == ''? 0: window.hash.length;
The Livescribe Pulse smartpen gets an app store. This little pen is quite amazing, and it just shows that the business model of an app store is already changing the market for every type of electronic device. So when does my…
The Ghostwire (DSiWare) game looks great and reminds me a lot of Fatal Frame.
FloorPlanner is an interesting bit of software built in Flash that allows you design your home in 2D and view in 3D.
The new Stargate Universe [Philosphocal] teaser looks awesome. I stopped watching Atlantis a bit ago because it got boring, I hope this pumps up the energy as BSG did. It has Lou Diamond Philips and Ming-Na in it, that could make…
Here’s a plethora of well designed RSS Feed icons for free!