Core-Plot: 2D Visualization Framework for Cocoa

Monday, 28 September 2009

core-plot:

Core Plot is a plotting framework for Mac OS X and iPhone OS. It provides 2D visualization of data, and is tightly integrated with Apple technologies like Core Animation, Core Data, and Cocoa Bindings.


Transparant PNG Files in Internet Explorer

Thursday, 17 September 2009

This is a great “set it and forget it” IE PNG Fix:

This script adds near-native PNG support with alpha opacity to IE 5.5 and 6. Now you can have full translucency and no more ugly grey borders! It requires only one line in your CSS file, and no changes to your website HTML. <IMG> tags and background images are both supported.

Haven’t had to use something like this in a long while, but this looks like a much better method than the other purely CSS or JavaScript techniques I’ve seen.


Yourls and AddToAny: A Better Approach

Wednesday, 16 September 2009

Pat from AddToAny was kind enough to comment on my previous post about getting Yourls and AddToAny work together. He offered a better approach that effectively removes the “via @AddToAny” attribution and keeps my own short urls intact on links shared through their service.

Here’s how to do it:

From the WordPress administration panel, go to Settings > Share/Save Buttons and in the “Additional Options” box, paste the following:

a2a_track_links='custom';
a2a_track_links_key = my_yourl;

The variable a2a_track_links_key is a placeholder for the URL you want shared. By default AddToAny will just take the current page’s location.href if you don’t set this key manually. Since everything in the “Additional Options” box is JavaScript (not PHP) we can’t just print the call to wp_ozh_yourls_geturl in order to get the short url for the current post. We have to use a placeholder variable called “my_yourl” which we’ll define with the short URL from within the blog post template itself (which is in PHP and can call wp_ozh_yourls_geturl).

In your theme’s single.php file, place this bit of JavaScript code right below the <?php get_header(); ?> call:

<script type="text/javascript">
var my_yourl = "<?php echo wp_ozh_yourls_geturl($post->ID); ?>";
</script>

Now, a2a_track_links_key is set to the short URL for the post on the current page and AddToAny will know to use that instead of the current page’s url.

The big upside here is that this will work with any of the services used through AddToAny and you still get their Smart Menus. Not to mention that you’re now free to upgrade the plugin without worrying about it breaking.

The only downside I see is that if you use the “Standalone Services” this doesn’t seem to work. (Which is why I’m not using any yet.) For example, you still get the double-shortened URL and the “via @AddToAny” attribution with the Standalone Twitter service. According to Pat, it looks like they’re working on updating this.

Overall this is a much better approach than my previous hackfest. My thanks to Pat and AddToAny for taking the time to help me fix this!


Getting Yourls and AddToAny to Play Nicely Together

Monday, 14 September 2009

UPDATE: Pat from AddToAny describes a better way to do this in the comments. I’ve written an updated article describing the new process.

I’ve been playing around with Yourls and it’s accompanying Wordpress Plugin as a personal link shortening and sharing service for Twitter. So far it’s been very handy. I also recently added a “Share/Save This Entry” widget to the bottom of my blog posts courtesy of the AddToAny WordPress Plugin. I noticed that AddToAny was using the full URL for the posts and wondered how hard it would be to get it to use my custom shortened urls instead. Turns out, it’s really easy as long as you have both of these plugins installed.

A word of warning… this involved a (very minor) edit to the AddToAny plugin’s source code. That means that it’ll most likely break if and when you update the AddToAny plugin.

Find this block of code in wp-content/plugins/add-to-any/add-to-any.php:

function A2A_SHARE_SAVE_link_vars() {
    global $post;

    $linkname        = get_the_title($post->ID);
    $linkname_enc    = rawurlencode( $linkname );
    $linkurl        = get_permalink($post->ID);
    $linkurl_enc    = rawurlencode( $linkurl );    

    return compact( 'linkname', 'linkname_enc', 'linkurl', 'linkurl_enc' );
}

… and replace get_permalink($post->ID) with wp_ozh_yourls_geturl($post->ID), like so:

function A2A_SHARE_SAVE_link_vars() {
    global $post;

    $linkname        = get_the_title($post->ID);
    $linkname_enc    = rawurlencode( $linkname );
    $linkurl        = wp_ozh_yourls_geturl($post->ID);
    $linkurl_enc    = rawurlencode( $linkurl );    

    return compact( 'linkname', 'linkname_enc', 'linkurl', 'linkurl_enc' );
}

All this does is replace the standard “get_permalink” call with a call from the Yourls WordPress plugin that’ll return the shortened url instead. If one doesn’t exist, it’ll create it first. Very handy and very easy.

Although this seems to work so far, I found a problem where AddToAny has a really lame “feature” that shortens urls and adds their own attribution to the end of the generated tweet. So, after hitting the “Send to Twitter” button from a post on my site, you end up with something like this:

HTML5 Enabling JavaScript for Internet Explorer http://bit.ly/666Gd via @AddToAny

What? Really? I’m not sure how they feel they can add their attribution to a link that is simply shared through their service and not discovered through their service, but that’s besides the point.

I googled around and even asked them via Twitter, but couldn’t find a way to disable this “feature.”

Hmm… now if only AddToAny didn’t automatically shorten my already shortened url on Twitter… Luckily, you can define custom services within the “Additional Options” section of the AddToAny Share/Save settings from within WordPress.

So, I added another service for Twitter:

a2a_custom_services = [
        ["Twitter",
                "http://twitter.com/home?status=A2A_LINKNAME_ENC%3A%20A2A_LINKURL_ENC",
                "http://example.com/wp-content/plugins/add-to-any/icons/twitter.png"
        ]
];

Be sure to change the url for the twitter icon as I’m just using an example. It looks something like this in the admin panel:

AddToAny Admin Screenshot

This allows you to keep the shorturl provided by Yourls. An added benefit is that it doesn’t go through AddToAny’s service proxy first. The only problem now is that you’ll have two Twitter buttons on the AddToAny popup:

Double Twitter Buttons

So, you’ll also need to add this CSS style declaration to your page to hide their existing Twitter service from the widget:

#a2apage_twitter.a2a_sss {
  display: none;
}

This is what you’ll end up with:

Custom Twitter Button

This is obviously not an optimal solution for a number of reasons. Firstly, it means you’ll end up having an odd number of items in the share overlay. I tried changing the number of services listed using one of the built-in options but it didn’t have any effect. (Most likely because I’m messing with their CSS directly.) Also, the custom service won’t take advantage of the smart menus where visitors services are displayed first and in bold. In the end though, I’m willing to sacrifice that for the sake of having my own attribution and short links.

Is there an easier way to do this? If there is, I’m all ears.


HTML5 Enabling JavaScript for Internet Explorer

Saturday, 12 September 2009

This script looks like a great little stopgap to enable HTML5 on Internet Explorer:

Since HTML5 is getting more attention by way of marking up our new pages, and the only way to get IE to acknowledge the new elements, such as <article>, is to use the HTML5 shiv, I’ve quickly put together a mini script that enables all the new elements.


Migrating from sfSimpleBlog to WordPress

Sunday, 19 July 2009

The sfSimpleBlogPlugin makes adding a simple blogging platform to any Symfony application very easy. It hasn’t really been actively developed for a long while, but it still sees a decent amount of use in the Symfony community simply because it’s so easy to setup and integrate with an existing Symfony project. I developed a site around 3 years ago that used sfSimpleBlog. The requirements for the blog were very minimal at the time so it was a good fit. Since then though, their blog has turned into a central part of the site and now they need something a little less simple.

I found it hard to believe that no one’s ever done this before, but a quick Google search wasn’t much help, so I wrote a pake task to export the sfSimpleBlog articles to an XML format that could be imported using WordPress’s built-in RSS importer. It’s very basic and you should be able to edit it to your needs. It should be noted that this was written for Symfony 1.0 so the format for pake tasks may have changed for Symfony 1.2.

Basic Usage

From the command line:

./symfony blog-export frontend prod

… where “frontend” is simply the application you want to load the config from and “prod” is the environment that should be used.

By default it makes a file called simple_blog_dump.xml in the root of your Symfony project. (You can change this filepath in the code itself if you need.) You can then import this file from your WordPress administration page.

The Code

Download this file and rename it to “myPakeBlogExport.php” inside of your project_root/data/tasks/. The filename must start with myPake since Symfony won’t load the task otherwise. Then run the pake task as mentioned in the section above.

UPDATE: It looks like my WordPress theme is mangling the following code block. Be sure to download and rename it instead. I’ll leave the code block here for reference:

<?php

// Written by Mark Quezada (mark [at] mirthlab dot com)

pake_desc('Export sfSimpleBlogPosts to wordpress xml.');
pake_task('blog-export', 'project_exists');

function run_blog_export($task, $args)
{
  if(!count($args))
  {
    throw new Exception('You must specify an application to load configuration info from (e.g. frontend).');
  }

  if(count($args) != 2) {
    throw new Exception('Please specify an environment (e.g. prod or dev).');
  }
  
  $app = $args[0];
  $env = $args[1];
  $con = _file_storage_get_connection($app, $env);
  
  
  $posts = sfSimpleBlogPostPeer::doSelect(new Criteria(), $con);

  $lines = array();
  foreach ($posts as $post)
  {
    $lines[] = '<item>';
    $lines[] = '  <pubDate>'.$post->getCreatedAt().'</pubDate>';
    foreach ($post->getsfSimpleBlogTags() as $tag)
    {
      $lines[] = '  <category>'.$tag->getTag().'</category>';
    }
    $lines[] = '  <title>'.$post->getTitle().'</title>';
    $lines[] = '  <content:encoded>'._blog_export_clean_content($post->getContent()).'</content:encoded>';

    foreach ($post->getsfSimpleBlogComments() as $comment)
    {
      $lines[] = '  <wp:comment>';
      $lines[] = '    <wp:comment_author>'.$comment->getAuthorName().'</wp:comment_author>';
      $lines[] = '    <wp:comment_author_email>'.$comment->getAuthorEmail().'</wp:comment_author_email>';
      $lines[] = '    <wp:comment_author_url>'.$comment->getAuthorUrl().'</wp:comment_author_url>';
      $lines[] = '    <wp:comment_date>'.$comment->getCreatedAt().'</wp:comment_date>';
      $lines[] = '    <wp:comment_content>'._blog_export_clean_content($comment->getContent()).'</wp:comment_content>';
      $lines[] = '    <wp:comment_approved>'.$comment->getIsModerated().'</wp:comment_approved>';
      $lines[] = '  </wp:comment>';
    }
    $lines[] = '</item>';
  }


  $handle = fopen("simple_blog_dump.xml", "w");
  foreach($lines as $line)
  {
    fwrite($handle, $line."\n");
  }
  fclose($handle);  
}



function _blog_export_get_connection($app, $env)
{
  // define constants
  define('SF_ROOT_DIR',    sfConfig::get('sf_root_dir'));
  define('SF_APP',         $app);
  define('SF_ENVIRONMENT', $env);
  define('SF_DEBUG',       false);
  require_once SF_ROOT_DIR.DIRECTORY_SEPARATOR.'apps'.DIRECTORY_SEPARATOR.SF_APP.DIRECTORY_SEPARATOR.'config'.DIRECTORY_SEPARATOR.'config.php';
  $connection = sfContext::getInstance()->getDatabaseConnection('propel');

  return $connection;
}

function _blog_export_clean_content($string)
{
  // check if the string contains html
  if (strlen($string) != strlen(strip_tags($string)))
  {
    // it does, remove newlines as the wordpress importer will automatically convert them (again) to <p> tags
    $string = str_replace("\r\n",'',$string);
    $string = str_replace("\n",'',$string);
    $string = str_replace("\r",'',$string);
  }
  
  // Note: I'm not removing newlines from posts that *don't* contain html since we want wordpress to add <p> tags in that case
  
  return $string;
}

Quick jQuery Tip: Triggering Effects Based on Visibility

Thursday, 09 July 2009

I often need to trigger an effect like “hide” or “show” on an element but only if it’s not already hidden or visible. Why is this important? Well, if you have elements that can be switched from visible to hidden independently, and then you try to hide an element that’s already hidden, the element will first be revealed and then hidden again causing random flashing or haphazard animations. This is especially noticeable with fade or blind effects since they take time to animate.

The solution is very easy with jQuery filters. Before using an effect, be sure you’re only operating on the elements that are either hidden or visible by using the :hidden and :visible filters:

$('.hidden_elements:hidden').show(); 
$('.visible_elements:visible').hide(); 

You can read up on the hidden and visible filters in the Selectors section of the jQuery Docs.


Clearing Floats in CSS

Wednesday, 01 July 2009

Clearing floats:

A common problem with float-based layouts is that the floats’ container doesn’t want to stretch up to accomodate the floats. If you want to add, say, a border around all floats (ie. a border around the container) you’ll have to command the browsers somehow to stretch up the container all the way.

I’ve found myself searching for this repeatedly so I’m linking to it here for posterity. The gist of it is to add a width and overflow property to the div containing the floating elements, like so:

div.container {
    overflow: hidden;
    width: 100%;
}

Using an SSH Config File to Ease Connections Between Servers

Tuesday, 09 June 2009

Fabien Potencier, (founder and lead developer of the Symfony Framework) shares a Quick SSH Tip:

Some time ago, I re-discover a neat trick to simplify the connection by using the .ssh/config file. I don’t know why I forgot about it, but as it seems that a lot of people around me do not know about this file either, here is a small post on how it can be used to your advantage.

Most SSH applications (like Terminal or iTerm for Mac OS X) allow you to save connection info, so this might not seem immediately useful compared to that. This differs in that it isn’t limited to one specific application. Every app will use the same SSH config file for the same user, so it won’t matter which app you’re using… you’ll still have access to these handy shortcuts. Neat.


Cross-Domain Ajax/XHR for Embedded Javascript Widgets

Wednesday, 03 June 2009

I’ve been looking for a solution to the problem of cross-domain XHR restrictions. Cross domain Ajax/HXR is necessary for creating a communications channel to and from embedded javascript widgets. The problem is simple: widgets embedded in a user’s site (blog, etc.) cannot instantiate Ajax/XHR requests because they do not reside on the same domain as the host serving the widget. This is an incredible bummer since it drastically limits what’s possible from an embedded javascript widget.

That’s where flXHR comes in:

flXHR [flĕkʹsər],(flex-er) is a client-based cross-browser, XHR-compatible tool for cross-domain Ajax (Flash) communication. It utilizes an invisible flXHR.swf instance that acts as sort of a client-side proxy for requests, combined with a Javascript object/module wrapper that exposes an identical interface to the native XMLHttpRequest (XHR) browser object, with a few helpful additions and a couple of minor limitations.

It’s an incredibly clever use for flash. (Apparently the concept has been around for a while.) I’ve used flash as a middle-man before with SWFUpload, but I’ve never thought to use it as a client-side proxy for cross-domain XHR. There’s also a jQuery plugin that allows you to replace jQuery’s standard ajax transport with a flXHR version. There are of course, some downsides, but in the end, it bridges the gap to richer widget interactions with minimal fuss.