<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom">

 <title>Dave Dash</title>
 <link href="http://davedash.com/tag/css/atom.xml" rel="self"/>
 <link href="http://davedash.com/tag/css"/>
 <updated>2012-01-17T21:54:19-08:00</updated>
 <id>http://davedash.com/</id>
 <author>
   <name>Dave Dash</name>
   <email>dd+atom1@davedash.com</email>
 </author>

 
 <entry>
   <title>Enabling a debug.css in django</title>
   <link href="http://davedash.com/2008/02/11/enabling-a-debugcss-in-django/"/>
   <updated>2008-02-11T00:00:00-08:00</updated>
   <id>http://davedash.com/2008/02/11/enabling-a-debugcss-in-django</id>
   <content type="html">&lt;p&gt;I like for extra magical stuff to occur when I am in development/debug mode.  One of those magical things is a a magic &lt;code&gt;debug.css&lt;/code&gt; style sheet.&lt;/p&gt;

&lt;p&gt;Django sets a &lt;code&gt;debug&lt;/code&gt; variable when the following conditions are met:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;django.core.context_processors.debug&lt;/code&gt; is listed under &lt;code&gt;TEMPLATE_CONTEXT_PROCESSORS&lt;/code&gt; and your IP address (127.0.0.1 if your using the standard development server) is listed under &lt;code&gt;INTERNAL_IPS&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then in your &lt;code&gt;base.html&lt;/code&gt; just add something like this:&lt;/p&gt;

&lt;div&gt;&lt;textarea name=&quot;code&quot; class=&quot;html&quot;&gt;
  
&lt;/textarea&gt;&lt;/div&gt;


&lt;p&gt;For my CSS I like to use the following:&lt;/p&gt;

&lt;div&gt;&lt;textarea name=&quot;code&quot; class=&quot;css&quot;&gt;
.incomplete { background:#c0c !important}
.incomplete .incomplete{background:#d0d !important}
.incomplete .incomplete .incomplete{background:#e0e !important}
.incomplete .incomplete .incomplete .incomplete{background:#f0f !important}
&lt;/textarea&gt;&lt;/div&gt;


&lt;p&gt;As I am developing my site, if I feel that a block of content isn't fully finished for whatever reason, I mark it with a class of &lt;code&gt;incomplete&lt;/code&gt;.  This results in a purple color (which I don't use on my site), the purpler it is... the more incomplete the content.&lt;/p&gt;

&lt;p&gt;It's like eating that stuff that makes your teeth red if you haven't brushed them enough.  Once all the purple's gone the site is ready for production.&lt;/p&gt;

&lt;p&gt;Eventually we can use all these hooks into the template to implement a symfony-style debug bar... later.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Enabling a debug.css in django</title>
   <link href="http://davedash.com/2008/02/11/enabling-a-debugcss-in-django/"/>
   <updated>2008-02-11T00:00:00-08:00</updated>
   <id>http://davedash.com/2008/02/11/enabling-a-debugcss-in-django</id>
   <content type="html">&lt;p&gt;I like for extra magical stuff to occur when I am in development/debug mode.  One of those magical things is a a magic &lt;code&gt;debug.css&lt;/code&gt; style sheet.&lt;/p&gt;

&lt;p&gt;Django sets a &lt;code&gt;debug&lt;/code&gt; variable when the following conditions are met:&lt;/p&gt;

&lt;p&gt;&lt;code&gt;django.core.context_processors.debug&lt;/code&gt; is listed under &lt;code&gt;TEMPLATE_CONTEXT_PROCESSORS&lt;/code&gt; and your IP address (127.0.0.1 if your using the standard development server) is listed under &lt;code&gt;INTERNAL_IPS&lt;/code&gt;.&lt;/p&gt;

&lt;p&gt;Then in your &lt;code&gt;base.html&lt;/code&gt; just add something like this:&lt;/p&gt;

&lt;div&gt;&lt;textarea name=&quot;code&quot; class=&quot;html&quot;&gt;
  
&lt;/textarea&gt;&lt;/div&gt;


&lt;p&gt;For my CSS I like to use the following:&lt;/p&gt;

&lt;div&gt;&lt;textarea name=&quot;code&quot; class=&quot;css&quot;&gt;
.incomplete { background:#c0c !important}
.incomplete .incomplete{background:#d0d !important}
.incomplete .incomplete .incomplete{background:#e0e !important}
.incomplete .incomplete .incomplete .incomplete{background:#f0f !important}
&lt;/textarea&gt;&lt;/div&gt;


&lt;p&gt;As I am developing my site, if I feel that a block of content isn't fully finished for whatever reason, I mark it with a class of &lt;code&gt;incomplete&lt;/code&gt;.  This results in a purple color (which I don't use on my site), the purpler it is... the more incomplete the content.&lt;/p&gt;

&lt;p&gt;It's like eating that stuff that makes your teeth red if you haven't brushed them enough.  Once all the purple's gone the site is ready for production.&lt;/p&gt;

&lt;p&gt;Eventually we can use all these hooks into the template to implement a symfony-style debug bar... later.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Table based layouts?  In this day in age?  Really?  How about grids?</title>
   <link href="http://davedash.com/2007/10/05/table-based-layouts-in-this-day-in-age-really-how-about-grids/"/>
   <updated>2007-10-05T00:00:00-07:00</updated>
   <id>http://davedash.com/2007/10/05/table-based-layouts-in-this-day-in-age-really-how-about-grids</id>
   <content type="html">&lt;p&gt;[tags]css, yui, grids, table, layout[/tags]&lt;/p&gt;

&lt;p&gt;I think there are three kinds of people:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;People who learned tables for layouts and went to CSS+&lt;code&gt;div&lt;/code&gt;s.&lt;/li&gt;
&lt;li&gt;People who learned tables for layouts and never needed to learn CSS+&lt;code&gt;div&lt;/code&gt;s (or insisted that this was way too complicated)&lt;/li&gt;
&lt;li&gt;People who never learned tables.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;I would argue in some ways the second class of people are right, tables are a lot easier.  Until you run into issues... and until you need to maintain your template code.&lt;/p&gt;

&lt;p&gt;Luckily there's grids.  Grids are easier than tables and easy to maintain and look at.  You can achieve just about anything with &lt;a href=&quot;http://developer.yahoo.com/yui/grids/&quot;&gt;grids&lt;/a&gt;.&lt;/p&gt;

&lt;!--next page--&gt;


&lt;!--more--&gt;


&lt;p&gt;Personally I like using &lt;a href=&quot;http://developer.yahoo.com/yui/&quot;&gt;Yahoo's YUI&lt;/a&gt; to get grid support.  It's a CSS framework in the same way that &lt;a href=&quot;http://jquery.com&quot;&gt;jQuery&lt;/a&gt; is a javascript framework or that &lt;a href=&quot;http://symfony-project.com/&quot;&gt;symfony&lt;/a&gt; is a PHP5 framework.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://developer.yahoo.com/yui/&quot;&gt;YUI&lt;/a&gt; will normalize all your elements and give you a standard way to change the size of text and elements and give you &lt;a href=&quot;http://developer.yahoo.com/yui/grids/&quot;&gt;grids&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So it helps to think of your layout in terms of grids... or columns.  &lt;a href=&quot;http://developer.yahoo.com/yui/grids/&quot;&gt;YUI grids&lt;/a&gt; supports some common combinations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.yui-g&lt;/code&gt; - 2 equal size containers (nest to get 4).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.yui-gb&lt;/code&gt; - 3 equal size containers&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.yui-gc&lt;/code&gt; - 2/3 - 1/3&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.yui-gd&lt;/code&gt; - 1/3 - 2/3&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.yui-ge&lt;/code&gt; - 3/4 - 1/4&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.yui-gf&lt;/code&gt; - 1/4 - 3/4&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Granted, this doesn't cover every scenario, but it's a start, and it's easy to build off of to create your own special sizes.&lt;/p&gt;

&lt;p&gt;So to create some magical columns you do the following:&lt;/p&gt;

&lt;div&gt;&lt;textarea name=&quot;code&quot; class=&quot;html&quot;&gt;
&lt;div class=&quot;yui-g&quot;&gt;
  &lt;div class=&quot;yui-u first&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;yui-u&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/textarea&gt;&lt;/div&gt;


&lt;p&gt;&lt;code&gt;yui-g&lt;/code&gt; can be substituted for any of the above classes.  &lt;code&gt;yui-u&lt;/code&gt; is your columns or grid cells.  &lt;code&gt;first&lt;/code&gt; indicates the first column since &lt;code&gt;:first&lt;/code&gt; isn't understood by some popular browsers.&lt;/p&gt;

&lt;p&gt;Now you know grids.  It's less complicated than the tabular equivalent:&lt;/p&gt;

&lt;div&gt;&lt;textarea name=&quot;code&quot; class=&quot;html&quot;&gt;
&lt;table class=&quot;layout&quot;&gt;
  &lt;tr class=&quot;first_row&quot;&gt;
    &lt;td class=&quot;col1&quot;&gt;&lt;/td&gt;
    &lt;td class=&quot;col2&quot;&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;/textarea&gt;&lt;/div&gt;


&lt;p&gt;With the framework in place, it's a lot easier to quickly adjust your layouts, and the readability is huge especially as your layouts grow.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Table based layouts?  In this day in age?  Really?  How about grids?</title>
   <link href="http://davedash.com/2007/10/05/table-based-layouts-in-this-day-in-age-really-how-about-grids/"/>
   <updated>2007-10-05T00:00:00-07:00</updated>
   <id>http://davedash.com/2007/10/05/table-based-layouts-in-this-day-in-age-really-how-about-grids</id>
   <content type="html">&lt;p&gt;[tags]css, yui, grids, table, layout[/tags]&lt;/p&gt;

&lt;p&gt;I think there are three kinds of people:&lt;/p&gt;

&lt;ol&gt;
&lt;li&gt;People who learned tables for layouts and went to CSS+&lt;code&gt;div&lt;/code&gt;s.&lt;/li&gt;
&lt;li&gt;People who learned tables for layouts and never needed to learn CSS+&lt;code&gt;div&lt;/code&gt;s (or insisted that this was way too complicated)&lt;/li&gt;
&lt;li&gt;People who never learned tables.&lt;/li&gt;
&lt;/ol&gt;


&lt;p&gt;I would argue in some ways the second class of people are right, tables are a lot easier.  Until you run into issues... and until you need to maintain your template code.&lt;/p&gt;

&lt;p&gt;Luckily there's grids.  Grids are easier than tables and easy to maintain and look at.  You can achieve just about anything with &lt;a href=&quot;http://developer.yahoo.com/yui/grids/&quot;&gt;grids&lt;/a&gt;.&lt;/p&gt;

&lt;!--next page--&gt;


&lt;!--more--&gt;


&lt;p&gt;Personally I like using &lt;a href=&quot;http://developer.yahoo.com/yui/&quot;&gt;Yahoo's YUI&lt;/a&gt; to get grid support.  It's a CSS framework in the same way that &lt;a href=&quot;http://jquery.com&quot;&gt;jQuery&lt;/a&gt; is a javascript framework or that &lt;a href=&quot;http://symfony-project.com/&quot;&gt;symfony&lt;/a&gt; is a PHP5 framework.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://developer.yahoo.com/yui/&quot;&gt;YUI&lt;/a&gt; will normalize all your elements and give you a standard way to change the size of text and elements and give you &lt;a href=&quot;http://developer.yahoo.com/yui/grids/&quot;&gt;grids&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So it helps to think of your layout in terms of grids... or columns.  &lt;a href=&quot;http://developer.yahoo.com/yui/grids/&quot;&gt;YUI grids&lt;/a&gt; supports some common combinations:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.yui-g&lt;/code&gt; - 2 equal size containers (nest to get 4).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.yui-gb&lt;/code&gt; - 3 equal size containers&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.yui-gc&lt;/code&gt; - 2/3 - 1/3&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.yui-gd&lt;/code&gt; - 1/3 - 2/3&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.yui-ge&lt;/code&gt; - 3/4 - 1/4&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.yui-gf&lt;/code&gt; - 1/4 - 3/4&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;Granted, this doesn't cover every scenario, but it's a start, and it's easy to build off of to create your own special sizes.&lt;/p&gt;

&lt;p&gt;So to create some magical columns you do the following:&lt;/p&gt;

&lt;div&gt;&lt;textarea name=&quot;code&quot; class=&quot;html&quot;&gt;
&lt;div class=&quot;yui-g&quot;&gt;
  &lt;div class=&quot;yui-u first&quot;&gt;&lt;/div&gt;
  &lt;div class=&quot;yui-u&quot;&gt;&lt;/div&gt;
&lt;/div&gt;
&lt;/textarea&gt;&lt;/div&gt;


&lt;p&gt;&lt;code&gt;yui-g&lt;/code&gt; can be substituted for any of the above classes.  &lt;code&gt;yui-u&lt;/code&gt; is your columns or grid cells.  &lt;code&gt;first&lt;/code&gt; indicates the first column since &lt;code&gt;:first&lt;/code&gt; isn't understood by some popular browsers.&lt;/p&gt;

&lt;p&gt;Now you know grids.  It's less complicated than the tabular equivalent:&lt;/p&gt;

&lt;div&gt;&lt;textarea name=&quot;code&quot; class=&quot;html&quot;&gt;
&lt;table class=&quot;layout&quot;&gt;
  &lt;tr class=&quot;first_row&quot;&gt;
    &lt;td class=&quot;col1&quot;&gt;&lt;/td&gt;
    &lt;td class=&quot;col2&quot;&gt;&lt;/td&gt;
  &lt;/tr&gt;
&lt;/table&gt;
&lt;/textarea&gt;&lt;/div&gt;


&lt;p&gt;With the framework in place, it's a lot easier to quickly adjust your layouts, and the readability is huge especially as your layouts grow.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>jQuery shortcut functions and jQuery plugins</title>
   <link href="http://davedash.com/2007/09/15/jquery-shortcut-functions-and-jquery-plugins/"/>
   <updated>2007-09-15T00:00:00-07:00</updated>
   <id>http://davedash.com/2007/09/15/jquery-shortcut-functions-and-jquery-plugins</id>
   <content type="html">&lt;p&gt;[tags]js, javascript, readability, yui, jquery, shortcuts[/tags]&lt;/p&gt;

&lt;p&gt;One of the the things that's kept me away from the YUI javascript libraries is longhand.  Or rather, the appeal to jQuery (and Prototype) was the almight $ shorthand.&lt;/p&gt;

&lt;p&gt;Of course there are times when it pays to write in long hand.  Marc Grabanski has written a fantastic &lt;a href=&quot;http://marcgrabanski.com/code/jquery-calendar/&quot;&gt;calendar plugin&lt;/a&gt; which uses a lot of jQuery shorthand.  &lt;code&gt;$()&lt;/code&gt;, &lt;code&gt;$.extend&lt;/code&gt; and whatnot are great for quick code, but disaster when you need to be in maximum compatibility mode.  For example, use jQuery with some other libraries and you can get disaster.  It's better to opt for the long-hand &lt;code&gt;jQuery&lt;/code&gt; and &lt;code&gt;jQuery.extend&lt;/code&gt; methods.  After some search and replaces, I may have gotten things right, but I think I need to talk to Marc Grabanski and make sure the changes I made make sense.&lt;/p&gt;

&lt;p&gt;So remember, long hand is great when other developers are using stuff and namespace conflicts are afoot ;)&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>resetting CSS list items</title>
   <link href="http://davedash.com/2007/09/01/resetting-css-list-items/"/>
   <updated>2007-09-01T00:00:00-07:00</updated>
   <id>http://davedash.com/2007/09/01/resetting-css-list-items</id>
   <content type="html">&lt;p&gt;[tags]css, symfony, blueprint, yui[/tags]&lt;/p&gt;

&lt;p&gt;Call me a purist, but I really believe that Blueprint should go the extra step as YUI (note: I'm a YUI CSS user dabbling in Blueprint) does and reset list items as well.  It's all about how you use your elements and what you consider as resetting, but I feel that a bullet added to a list is something that should be removed in a proper reset.css file.&lt;/p&gt;

&lt;p&gt;Different browsers are going to have their own ways of rendering bullets and really the developer should explicitly inform us how they would like their lists rendered.&lt;/p&gt;

&lt;p&gt;Personally, most of my list items are lists of links as in menus, which require no bullets usually.  This is probably the source of my bias.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>resetting CSS list items</title>
   <link href="http://davedash.com/2007/09/01/resetting-css-list-items/"/>
   <updated>2007-09-01T00:00:00-07:00</updated>
   <id>http://davedash.com/2007/09/01/resetting-css-list-items</id>
   <content type="html">&lt;p&gt;[tags]css, symfony, blueprint, yui[/tags]&lt;/p&gt;

&lt;p&gt;Call me a purist, but I really believe that Blueprint should go the extra step as YUI (note: I'm a YUI CSS user dabbling in Blueprint) does and reset list items as well.  It's all about how you use your elements and what you consider as resetting, but I feel that a bullet added to a list is something that should be removed in a proper reset.css file.&lt;/p&gt;

&lt;p&gt;Different browsers are going to have their own ways of rendering bullets and really the developer should explicitly inform us how they would like their lists rendered.&lt;/p&gt;

&lt;p&gt;Personally, most of my list items are lists of links as in menus, which require no bullets usually.  This is probably the source of my bias.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>sfBlueprintPlugin: Train of thought development</title>
   <link href="http://davedash.com/2007/08/30/sfblueprintplugin-train-of-thought-development/"/>
   <updated>2007-08-30T00:00:00-07:00</updated>
   <id>http://davedash.com/2007/08/30/sfblueprintplugin-train-of-thought-development</id>
   <content type="html">&lt;p&gt;I've been creating some dummy projects for my presentations at &lt;a href=&quot;http://symfonycamp.com/&quot;&gt;SymfonyCamp&lt;/a&gt; and decided now would be a good time to learn using the Blueprint CSS framework.  It's a bit different than YUI which I've been using heavily, but it has some potential.&lt;/p&gt;

&lt;p&gt;Of course, instead of just downloading the framework, I made &lt;a href=&quot;http://trac.symfony-project.com/trac/browser/plugins/sfBlueprintPlugin&quot;&gt;a plugin&lt;/a&gt; for symfony.  It's not much yet, but eventually I'll throw in some helpers.&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;

&lt;p&gt;[tags]css, symfony, blueprint, plugins, symfony camp, camp, yui[/tags]&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>sfBlueprintPlugin: Train of thought development</title>
   <link href="http://davedash.com/2007/08/30/sfblueprintplugin-train-of-thought-development/"/>
   <updated>2007-08-30T00:00:00-07:00</updated>
   <id>http://davedash.com/2007/08/30/sfblueprintplugin-train-of-thought-development</id>
   <content type="html">&lt;p&gt;I've been creating some dummy projects for my presentations at &lt;a href=&quot;http://symfonycamp.com/&quot;&gt;SymfonyCamp&lt;/a&gt; and decided now would be a good time to learn using the Blueprint CSS framework.  It's a bit different than YUI which I've been using heavily, but it has some potential.&lt;/p&gt;

&lt;p&gt;Of course, instead of just downloading the framework, I made &lt;a href=&quot;http://trac.symfony-project.com/trac/browser/plugins/sfBlueprintPlugin&quot;&gt;a plugin&lt;/a&gt; for symfony.  It's not much yet, but eventually I'll throw in some helpers.&lt;/p&gt;

&lt;p&gt;Enjoy!&lt;/p&gt;

&lt;p&gt;[tags]css, symfony, blueprint, plugins, symfony camp, camp, yui[/tags]&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Symfony Camp: Ajax and Zend, what would you like to know?</title>
   <link href="http://davedash.com/2007/08/16/symfony-camp-ajax-and-zend-what-would-you-like-to-know/"/>
   <updated>2007-08-16T00:00:00-07:00</updated>
   <id>http://davedash.com/2007/08/16/symfony-camp-ajax-and-zend-what-would-you-like-to-know</id>
   <content type="html">&lt;p&gt;[tags]symfonyCamp, symfony, netherlands, ajax, zend search lucene, zsl, jquery[/tags]&lt;/p&gt;

&lt;p&gt;I've been asked to speak at &lt;a href=&quot;http://www.symfonycamp.com/&quot;&gt;SymfonyCamp&lt;/a&gt; (&lt;code&gt;symfony['camp']&lt;/code&gt;) next month (you should all go if you can) and I thought I'd present as well as I could on Ajax and the Zend Framework Bridge (including Zend Search Lucene).&lt;/p&gt;

&lt;p&gt;If you're attending the camp and/or would like to hear about these topics please let me know any specific questions you might have about &quot;&lt;a href=&quot;http://symfony-project.com/&quot;&gt;symfony&lt;/a&gt; and Ajax&quot; and &quot;symfony and Zend&quot; and I'll try to address them in my presentations.&lt;/p&gt;

&lt;p&gt;If you are unable to go fear not, I'll try to post my notes on this site.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>FBML and CSS background images</title>
   <link href="http://davedash.com/2007/08/11/fbml-and-css-background-images/"/>
   <updated>2007-08-11T00:00:00-07:00</updated>
   <id>http://davedash.com/2007/08/11/fbml-and-css-background-images</id>
   <content type="html">&lt;p&gt;I've been tediously building out the new &lt;a href=&quot;http://reviewsby.us/&quot;&gt;reviewsby.us&lt;/a&gt; app for Facebook and I ran into some problem when I tried to embed this CSS:&lt;/p&gt;

&lt;div&gt;&lt;textarea name=&quot;code&quot; class=&quot;css&quot;&gt;
input.openid_login {
            background: url(&quot;http://openid.net/login-bg.gif&quot;) no-repeat #fff;
   background-position: 0 50%;
          padding-left: 18px;
}
&lt;/textarea&gt;&lt;/div&gt;


&lt;p&gt;The CSS worked fine, just now background image.  The fix is mentioned in &lt;a href=&quot;http://www.facebook.com/topic.php?uid=2205007948&amp;amp;topic=5140&amp;amp;post=50818&amp;amp;pwstdfy=0434dec4ce75745f05b7396611234b7c#post50818&quot;&gt;this post&lt;/a&gt; which is to repeat the &lt;code&gt;background&lt;/code&gt; statement:&lt;/p&gt;

&lt;div&gt;&lt;textarea name=&quot;code&quot; class=&quot;css&quot;&gt;
input.openid_login {
            background: url(&quot;http://openid.net/login-bg.gif&quot;) no-repeat #fff;
            background: url(&quot;http://openid.net/login-bg.gif&quot;) no-repeat #fff;
   background-position: 0 50%;
          padding-left: 18px;
}
&lt;/textarea&gt;&lt;/div&gt;


&lt;p&gt;Voila, it works.  Hopefully this hack won't be necessary in later versions of the Platform.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>FBML and embedded CMS</title>
   <link href="http://davedash.com/2007/08/04/fbml-and-embedded-cms/"/>
   <updated>2007-08-04T00:00:00-07:00</updated>
   <id>http://davedash.com/2007/08/04/fbml-and-embedded-cms</id>
   <content type="html">&lt;p&gt;[tags]fbml, css, reviewsby.us, partials, symfony, sfFacebookPlatformPlugin[/tags]&lt;/p&gt;

&lt;p&gt;One problem of going the FBML route&lt;sup id=&quot;#fbmlcss_fnr_1&quot;&gt;&lt;a href=&quot;#fbmlcss_fn_1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; is CSS styles.  You can't link to external style sheets so you need to embed everything.&lt;/p&gt;

&lt;p&gt;I took the liberty of using a partial that contains all the useful CSS that I use in our app.  Now we can just embed it in our layout by doing:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;?php include_partial('sfFacebook/css');?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The following classes are useful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.app_content&lt;/code&gt; is the div surrounding the main content of the page.  It gives the canvas some padding (actually it gives itself some margin as not to butt-up against the canvas.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.box&lt;/code&gt; this defines the classic facebook box with a dark blue border at the top and with headers that have the lighter blue background and dark blue text.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.box .header&lt;/code&gt; the header for the box described above.  Use an &lt;code&gt;h2&lt;/code&gt; for the title.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.box .content&lt;/code&gt; the main content section of a box, has a bit of padding.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&quot;footnotes&quot;&gt;
&lt;ol&gt;
&lt;li id=&quot;fbmlcss_fn_1&quot;&gt;I'm not completely convinced that the
&lt;a href=&quot;http://reviewsby.us/&quot;&gt;reviewsby.us&lt;/a&gt; app for facebook should be using FBML.

&lt;a href=&quot;#fbmlcss_fnr_1&quot; class=&quot;footnoteBackLink&quot;  title=&quot;Jump back to footnote  in the text.&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;

</content>
 </entry>
 
 <entry>
   <title>FBML and embedded CMS</title>
   <link href="http://davedash.com/2007/08/04/fbml-and-embedded-cms/"/>
   <updated>2007-08-04T00:00:00-07:00</updated>
   <id>http://davedash.com/2007/08/04/fbml-and-embedded-cms</id>
   <content type="html">&lt;p&gt;[tags]fbml, css, reviewsby.us, partials, symfony, sfFacebookPlatformPlugin[/tags]&lt;/p&gt;

&lt;p&gt;One problem of going the FBML route&lt;sup id=&quot;#fbmlcss_fnr_1&quot;&gt;&lt;a href=&quot;#fbmlcss_fn_1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt; is CSS styles.  You can't link to external style sheets so you need to embed everything.&lt;/p&gt;

&lt;p&gt;I took the liberty of using a partial that contains all the useful CSS that I use in our app.  Now we can just embed it in our layout by doing:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;?php include_partial('sfFacebook/css');?&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;The following classes are useful:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;code&gt;.app_content&lt;/code&gt; is the div surrounding the main content of the page.  It gives the canvas some padding (actually it gives itself some margin as not to butt-up against the canvas.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.box&lt;/code&gt; this defines the classic facebook box with a dark blue border at the top and with headers that have the lighter blue background and dark blue text.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.box .header&lt;/code&gt; the header for the box described above.  Use an &lt;code&gt;h2&lt;/code&gt; for the title.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;.box .content&lt;/code&gt; the main content section of a box, has a bit of padding.&lt;/li&gt;
&lt;/ul&gt;


&lt;div class=&quot;footnotes&quot;&gt;
&lt;ol&gt;
&lt;li id=&quot;fbmlcss_fn_1&quot;&gt;I'm not completely convinced that the
&lt;a href=&quot;http://reviewsby.us/&quot;&gt;reviewsby.us&lt;/a&gt; app for facebook should be using FBML.

&lt;a href=&quot;#fbmlcss_fnr_1&quot; class=&quot;footnoteBackLink&quot;  title=&quot;Jump back to footnote  in the text.&quot;&gt;&amp;#8617;&lt;/a&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;

</content>
 </entry>
 
 <entry>
   <title>Equal height columns with jQuery</title>
   <link href="http://davedash.com/2007/05/22/equal-height-columns-with-jquery/"/>
   <updated>2007-05-22T00:00:00-07:00</updated>
   <id>http://davedash.com/2007/05/22/equal-height-columns-with-jquery</id>
   <content type="html">&lt;p&gt;[tags]css, jQuery, layout, javascript, equal, columns, equal columns[/tags]&lt;/p&gt;

&lt;p&gt;I've seen a few examples of how to equalize column heights using javascript, and none of them seem appealing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.tomdeater.com/jquery/equalize_columns/&quot;&gt;jquery.equalizecols.js&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;This required a few other libraries, and I wanted more flexibility (e.g. where the column should grow in order to equalize)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.projectseven.com/tutorials/css/pvii_columns/index.htm&quot;&gt;Project 7&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;The Project 7 approach was the most interesting, but the code seemed a bit messy and not so open source friendly (even thought it might have been).  It would let you specify which element was to grow inside a column.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.html.it/articoli/nifty/index.html&quot;&gt;Nifty Corners&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;I had trouble with the syntax, but I liked how it just created a new element out of thin air...&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;So I wrote my own:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$(&quot;#col1, #col2&quot;).equalizeCols();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;will equalize the columns as expected&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$(&quot;#col1, #col2&quot;).equalizeCols(&quot;p,p&quot;);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;will equalize the columns and add the extra space after the &lt;code&gt;p&lt;/code&gt; tag in &lt;code&gt;#col1&lt;/code&gt; or &lt;code&gt;#col2&lt;/code&gt; (whichever is shorter).&lt;/p&gt;

&lt;p&gt;Here's our function:&lt;/p&gt;

&lt;div&gt;&lt;textarea name=&quot;code&quot; class=&quot;js&quot;&gt;

(function($) {
  $.fn.equalizeCols = function(children){
    var child = Array(0);
    if (children) child = children.split(&quot;,&quot;);
    var maxH = 0;
    this.each(
      function(i) 
      {
        if (this.offsetHeight&gt;maxH) maxH = this.offsetHeight;
      }
    ).css(&quot;height&quot;, &quot;auto&quot;).each(
      function(i)
      {
        var gap = maxH-this.offsetHeight;
        if (gap &gt; 0)
        {
          t = document.createElement('div');
          $(t).attr(&quot;class&quot;,&quot;fill&quot;).css(&quot;height&quot;,gap+&quot;px&quot;);
          if (child.length &gt; i)
          {
            $(this).find(child[i]).children(':last-child').after(t);
          } 
          else 
          {
            $(this).children(':last-child').after(t);
          }
        }
      }  
    );
    
  }
})(jQuery);

&lt;/textarea&gt;&lt;/div&gt;


&lt;p&gt;This requires jQuery of course, and it hasn't been tested much.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Equal height columns with jQuery</title>
   <link href="http://davedash.com/2007/05/22/equal-height-columns-with-jquery/"/>
   <updated>2007-05-22T00:00:00-07:00</updated>
   <id>http://davedash.com/2007/05/22/equal-height-columns-with-jquery</id>
   <content type="html">&lt;p&gt;[tags]css, jQuery, layout, javascript, equal, columns, equal columns[/tags]&lt;/p&gt;

&lt;p&gt;I've seen a few examples of how to equalize column heights using javascript, and none of them seem appealing:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;a href=&quot;http://www.tomdeater.com/jquery/equalize_columns/&quot;&gt;jquery.equalizecols.js&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;This required a few other libraries, and I wanted more flexibility (e.g. where the column should grow in order to equalize)&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.projectseven.com/tutorials/css/pvii_columns/index.htm&quot;&gt;Project 7&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;The Project 7 approach was the most interesting, but the code seemed a bit messy and not so open source friendly (even thought it might have been).  It would let you specify which element was to grow inside a column.&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href=&quot;http://www.html.it/articoli/nifty/index.html&quot;&gt;Nifty Corners&lt;/a&gt;

&lt;ul&gt;
&lt;li&gt;I had trouble with the syntax, but I liked how it just created a new element out of thin air...&lt;/li&gt;
&lt;/ul&gt;
&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;So I wrote my own:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$(&quot;#col1, #col2&quot;).equalizeCols();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;will equalize the columns as expected&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;$(&quot;#col1, #col2&quot;).equalizeCols(&quot;p,p&quot;);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;will equalize the columns and add the extra space after the &lt;code&gt;p&lt;/code&gt; tag in &lt;code&gt;#col1&lt;/code&gt; or &lt;code&gt;#col2&lt;/code&gt; (whichever is shorter).&lt;/p&gt;

&lt;p&gt;Here's our function:&lt;/p&gt;

&lt;div&gt;&lt;textarea name=&quot;code&quot; class=&quot;js&quot;&gt;

(function($) {
  $.fn.equalizeCols = function(children){
    var child = Array(0);
    if (children) child = children.split(&quot;,&quot;);
    var maxH = 0;
    this.each(
      function(i) 
      {
        if (this.offsetHeight&gt;maxH) maxH = this.offsetHeight;
      }
    ).css(&quot;height&quot;, &quot;auto&quot;).each(
      function(i)
      {
        var gap = maxH-this.offsetHeight;
        if (gap &gt; 0)
        {
          t = document.createElement('div');
          $(t).attr(&quot;class&quot;,&quot;fill&quot;).css(&quot;height&quot;,gap+&quot;px&quot;);
          if (child.length &gt; i)
          {
            $(this).find(child[i]).children(':last-child').after(t);
          } 
          else 
          {
            $(this).children(':last-child').after(t);
          }
        }
      }  
    );
    
  }
})(jQuery);

&lt;/textarea&gt;&lt;/div&gt;


&lt;p&gt;This requires jQuery of course, and it hasn't been tested much.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Textmate Snippets for YUI em calculations</title>
   <link href="http://davedash.com/2007/05/08/textmate-snippets-for-yui-em-calculations/"/>
   <updated>2007-05-08T00:00:00-07:00</updated>
   <id>http://davedash.com/2007/05/08/textmate-snippets-for-yui-em-calculations</id>
   <content type="html">&lt;p&gt;[tags]yui, yahoo, css, snippet, textmate, ems, px[/tags]&lt;/p&gt;

&lt;p&gt;If you use &lt;a href=&quot;http://developer.yahoo.com/yui/grids/&quot;&gt;YUI grid layouts&lt;/a&gt; you'll notice that &lt;code&gt;ems&lt;/code&gt; are the preferred units and for good reason.  But ems don't make sense to people like us who want to be super precise down to the pixel... pixels make sense.&lt;/p&gt;

&lt;p&gt;So type in a number select it and run this &lt;code&gt;ruby&lt;/code&gt; script as a TextMate command (that outputs as a snippet):&lt;/p&gt;

&lt;div&gt;&lt;textarea name=&quot;code&quot; class=&quot;ruby&quot; cols=&quot;100&quot; rows=&quot;15&quot;&gt;
#!/usr/bin/env ruby
#
# This script will do the necessary YUI calculations from px to ems
#
# The result is inserted as a snippet, so it's
# possible to tab through the place holders.

# validate input
input    = ENV['TM_SELECTED_TEXT'].to_i;
width    = input.to_f/13
ie_width = width * 0.9759

print &quot;${1:width}:&quot;+width.to_s+&quot;em;*$1:&quot;+ie_width.to_s+&quot;em;$0&quot;
&lt;/textarea&gt;&lt;/div&gt;


&lt;p&gt;You'll have the proper tab stops to change the newly calculated &lt;code&gt;ems&lt;/code&gt; from &lt;code&gt;width&lt;/code&gt; to &lt;code&gt;margin-left&lt;/code&gt; or &lt;code&gt;margin-right&lt;/code&gt; or whatever it is you desire.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Textmate Snippets for YUI em calculations</title>
   <link href="http://davedash.com/2007/05/08/textmate-snippets-for-yui-em-calculations/"/>
   <updated>2007-05-08T00:00:00-07:00</updated>
   <id>http://davedash.com/2007/05/08/textmate-snippets-for-yui-em-calculations</id>
   <content type="html">&lt;p&gt;[tags]yui, yahoo, css, snippet, textmate, ems, px[/tags]&lt;/p&gt;

&lt;p&gt;If you use &lt;a href=&quot;http://developer.yahoo.com/yui/grids/&quot;&gt;YUI grid layouts&lt;/a&gt; you'll notice that &lt;code&gt;ems&lt;/code&gt; are the preferred units and for good reason.  But ems don't make sense to people like us who want to be super precise down to the pixel... pixels make sense.&lt;/p&gt;

&lt;p&gt;So type in a number select it and run this &lt;code&gt;ruby&lt;/code&gt; script as a TextMate command (that outputs as a snippet):&lt;/p&gt;

&lt;div&gt;&lt;textarea name=&quot;code&quot; class=&quot;ruby&quot; cols=&quot;100&quot; rows=&quot;15&quot;&gt;
#!/usr/bin/env ruby
#
# This script will do the necessary YUI calculations from px to ems
#
# The result is inserted as a snippet, so it's
# possible to tab through the place holders.

# validate input
input    = ENV['TM_SELECTED_TEXT'].to_i;
width    = input.to_f/13
ie_width = width * 0.9759

print &quot;${1:width}:&quot;+width.to_s+&quot;em;*$1:&quot;+ie_width.to_s+&quot;em;$0&quot;
&lt;/textarea&gt;&lt;/div&gt;


&lt;p&gt;You'll have the proper tab stops to change the newly calculated &lt;code&gt;ems&lt;/code&gt; from &lt;code&gt;width&lt;/code&gt; to &lt;code&gt;margin-left&lt;/code&gt; or &lt;code&gt;margin-right&lt;/code&gt; or whatever it is you desire.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>TextMate + YUI = YUI snippets!</title>
   <link href="http://davedash.com/2007/04/30/textmate-yui-yui-snippets/"/>
   <updated>2007-04-30T00:00:00-07:00</updated>
   <id>http://davedash.com/2007/04/30/textmate-yui-yui-snippets</id>
   <content type="html">&lt;p&gt;I do a lot of &lt;a href=&quot;http://developer.yahoo.com/yui/grids/&quot;&gt;YUI grid layouts&lt;/a&gt; and I love the nestable grids:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;yui-g$1&quot;&amp;gt; 
    &amp;lt;div class=&quot;yui-u first&quot;&amp;gt;
        $2
    &amp;lt;/div&amp;gt;
    &amp;lt;div class=&quot;yui-u&quot;&amp;gt;
        $3
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There's a tab stop after &lt;code&gt;yui-g&lt;/code&gt; in case you want to use one of the variants (&lt;code&gt;yui-gb&lt;/code&gt;, &lt;code&gt;yui-gc&lt;/code&gt;, etc).&lt;/p&gt;

&lt;p&gt;I'm working on a site that uses two equal width columns... a lot... so this comes in quite handy.  So long tables.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>TextMate + YUI = YUI snippets!</title>
   <link href="http://davedash.com/2007/04/30/textmate-yui-yui-snippets/"/>
   <updated>2007-04-30T00:00:00-07:00</updated>
   <id>http://davedash.com/2007/04/30/textmate-yui-yui-snippets</id>
   <content type="html">&lt;p&gt;I do a lot of &lt;a href=&quot;http://developer.yahoo.com/yui/grids/&quot;&gt;YUI grid layouts&lt;/a&gt; and I love the nestable grids:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;div class=&quot;yui-g$1&quot;&amp;gt; 
    &amp;lt;div class=&quot;yui-u first&quot;&amp;gt;
        $2
    &amp;lt;/div&amp;gt;
    &amp;lt;div class=&quot;yui-u&quot;&amp;gt;
        $3
    &amp;lt;/div&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;There's a tab stop after &lt;code&gt;yui-g&lt;/code&gt; in case you want to use one of the variants (&lt;code&gt;yui-gb&lt;/code&gt;, &lt;code&gt;yui-gc&lt;/code&gt;, etc).&lt;/p&gt;

&lt;p&gt;I'm working on a site that uses two equal width columns... a lot... so this comes in quite handy.  So long tables.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>How to make Prototype Window Class as easy as Lightbox Gone Wild</title>
   <link href="http://davedash.com/2006/11/13/how-to-make-prototype-window-class-as-easy-as-lightbox-gone-wild/"/>
   <updated>2006-11-13T00:00:00-08:00</updated>
   <id>http://davedash.com/2006/11/13/how-to-make-prototype-window-class-as-easy-as-lightbox-gone-wild</id>
   <content type="html">&lt;p&gt;I like the way that &lt;a href=&quot;http://particletree.com/features/lightbox-gone-wild/&quot; title=&quot;Lightbox Gone Wild&quot;&gt;Lightbox Gone Wild&lt;/a&gt; will automatically pickup any links with the &lt;code&gt;class=lbOn&lt;/code&gt;, but I wanted to use (at some point) &lt;a href=&quot;http://prototype-window.xilinus.com/&quot; title=&quot;Prototype Window Class&quot;&gt;Prototype Window Class&lt;/a&gt; instead.&lt;/p&gt;

&lt;p&gt;Luckily &lt;a href=&quot;http://prototype-window.xilinus.com/&quot; title=&quot;Prototype Window Class&quot;&gt;PWC&lt;/a&gt; is built on Prototype which means we've already loaded a helpful library.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;In order to take all &lt;code&gt;class=lbOn&lt;/code&gt; objects and run them through &lt;a href=&quot;http://prototype-window.xilinus.com/&quot; title=&quot;Prototype Window Class&quot;&gt;PWC&lt;/a&gt; we just write a simple loop and iterate.&lt;/p&gt;

&lt;p&gt;So here's the low-down:&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;Download &lt;a href=&quot;http://prototype-window.xilinus.com/&quot; title=&quot;Prototype Window Class&quot;&gt;PWC&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;Copy window.js&lt;/li&gt;
&lt;li&gt;Use the included prototype &amp;amp; script.aculo.us if you don't already include it in your page&lt;/li&gt;
&lt;li&gt;copy any themes you wish to use.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;In your page add this bit of JavaScript:&lt;/p&gt;

&lt;div&gt;&lt;textarea name=&quot;code&quot; class=&quot;js&quot;&gt;
    var mylb = Class.create();
    
    mylb.prototype = {
        initialize: function(ctrl) {
            this.content = ctrl.href;
            Event.observe(ctrl, 'click', this.activate.bindAsEventListener(this), false);
            ctrl.onclick = function(){return false;};
            },
    
            // Turn everything on - mainly the IE fixes
            activate: function(){
                var win = new Window('window_id', {className: &quot;alphacube&quot;,title: &quot;Tour&quot;, url: this.content, width:700, height:500});
                win.setDestroyOnClose();
                win.showCenter(true);
            }
        }

        lbox = document.getElementsByClassName('lbOn');
        for(i = 0; i &lt; lbox.length; i++) {
            valid = new mylb(lbox[i]);
        }
&lt;/textarea&gt;&lt;/div&gt;


&lt;p&gt;So, this code simply looks for all the anchor tags with &lt;code&gt;class=lbOn&lt;/code&gt; and then  creates a new &lt;code&gt;mylb&lt;/code&gt; instance for each anchor.  The end.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Cropping Images using DHTML (Prototype) and symfony</title>
   <link href="http://davedash.com/2006/09/16/cropping-images-using-dhtml-prototype-and-symfony/"/>
   <updated>2006-09-16T00:00:00-07:00</updated>
   <id>http://davedash.com/2006/09/16/cropping-images-using-dhtml-prototype-and-symfony</id>
   <content type="html">&lt;p&gt;&lt;a href=&quot;http://demos.spindrop.us/image_cropper/&quot;&gt;&lt;img src=&quot;http://demos.spindrop.us/image_cropper/images/screenshot.png&quot; style=&quot;float:left;margin-right:1em&quot; /&gt;&lt;/a&gt;&lt;/p&gt;

&lt;p&gt;&lt;strong&gt;Note:&lt;/strong&gt; Like many of my tutorials, you don't &lt;em&gt;need&lt;/em&gt; &lt;a href=&quot;http://symfony-project.com/&quot;&gt;symfony&lt;/a&gt;, just &lt;a href=&quot;http://php.net/&quot;&gt;PHP&lt;/a&gt;.  However, I develop in &lt;a href=&quot;http://symfony-project.com/&quot;&gt;symfony&lt;/a&gt; and take advantage of the &lt;acronym title=&quot;Model Viewer Controller&quot;&gt;MVC&lt;/acronym&gt;-support that it offers.&lt;/p&gt;

&lt;p&gt;Years ago when I was working on a photo gallery for &lt;a href=&quot;http://davedash.com/&quot;&gt;davedash.com&lt;/a&gt; I got the art of making tumbnails down fairly well.  It was automated and didn't allow for specifying how the thumbnail should be made.  With dozens of photos (which was a lot back then), when would I find that kind of time.&lt;/p&gt;

&lt;p&gt;Flashback to today, for &lt;a href=&quot;http://workface.com/&quot;&gt;my company&lt;/a&gt;... we want users with avatars... but nothing too large.  Maybe a nice 80x80 picture.  Well the coolest &lt;acronym title=&quot;User Interface&quot;&gt;UI&lt;/acronym&gt; I've seen was Apple's Address Book which let you use this slider mechanism to crop a fixed sized image from a larger image.&lt;/p&gt;

&lt;p&gt;Here's a &lt;a href=&quot;http://demos.spindrop.us/image_cropper/&quot;&gt;demo&lt;/a&gt;.&lt;/p&gt;

&lt;!--more--&gt;


&lt;h3&gt;Overview&lt;/h3&gt;

&lt;p&gt;The front-end &lt;acronym title=&quot;Graphical User Interface&quot;&gt;GUI&lt;/acronym&gt; is based on code from &lt;a href=&quot;http://digg.com/&quot;&gt;digg&lt;/a&gt; which is based on the look and feel (as near as I can tell) from Apple.&lt;/p&gt;

&lt;p&gt;The &lt;acronym title=&quot;Graphical User Interface&quot;&gt;GUI&lt;/acronym&gt; provides a clever visual way of telling the server how to chop the image.  The gist is this, sliding the image around and zooming in and out change a few form values that get passed to another script which uses this data to produce the image.&lt;/p&gt;

&lt;h3&gt;Frontend: What would you like to crop?&lt;/h3&gt;

&lt;p&gt;In this tutorial, we're going to be cropping an 80x80 avatar from an uploaded image.  The front-end requires the correct mix of Javascript, &lt;acronym title=&quot;Cascading Style Sheets&quot;&gt;CSS&lt;/acronym&gt;, &lt;acronym title=&quot;HypterText Markup Languag&quot;&gt;HTML&lt;/acronym&gt; and images.  The Javascript sets up the initial placements of the image and the controls.  The &lt;acronym title=&quot;Cascading Style Sheets&quot;&gt;CSS&lt;/acronym&gt; presents some necessary styling.  The images makeup some of the controls.  The &lt;acronym title=&quot;HyperText Markup Language&quot;&gt;HTML&lt;/acronym&gt; glues everything together.&lt;/p&gt;

&lt;h4&gt;&lt;acronym title=&quot;HyperText Markup Language&quot;&gt;HTML&lt;/acronym&gt;&lt;/h4&gt;

&lt;p&gt;Let's work on our &lt;acronym title=&quot;HyperText Markup Language&quot;&gt;HTML&lt;/acronym&gt; first.  Since I used &lt;a href=&quot;http://symfony-project.com/&quot;&gt;symfony&lt;/a&gt;, I created a &lt;code&gt;crop&lt;/code&gt; action for a &lt;code&gt;userpics&lt;/code&gt; module.  So in our &lt;code&gt;cropSuccess.php&lt;/code&gt; template:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;div id=&quot;ava&quot;&amp;gt;
    &amp;lt;?php echo form_tag(&quot;userpics/crop&quot;) ?&amp;gt;
        &amp;lt;div id=&quot;ava_img&quot;&amp;gt;
            &amp;lt;div id=&quot;ava_overlay&quot;&amp;gt;&amp;lt;/div&amp;gt;
            &amp;lt;div id=&quot;ava_drager&quot;&amp;gt;&amp;lt;/div&amp;gt;
            &amp;lt;img src=&quot;&amp;lt;?php echo $image ?&amp;gt;&quot; id=&quot;avatar&quot; /&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;div id=&quot;ava_slider&quot;&amp;gt;&amp;lt;div id=&quot;ava_handle&quot;&amp;gt;&amp;lt;/div&amp;gt;&amp;lt;/div&amp;gt;
        &amp;lt;input type=&quot;hidden&quot; id=&quot;ava_width&quot; name=&quot;width&quot; value=&quot;80&quot; /&amp;gt;
        &amp;lt;input type=&quot;hidden&quot; id=&quot;ava_x&quot; name=&quot;x&quot; value=&quot;100&quot; /&amp;gt;
        &amp;lt;input type=&quot;hidden&quot; id=&quot;ava_y&quot; name=&quot;y&quot; value=&quot;100&quot; /&amp;gt;
        &amp;lt;input type=&quot;hidden&quot; id=&quot;ava_image&quot; name=&quot;file&quot; value=&quot;&amp;lt;?php echo $image ?&amp;gt;&quot; /&amp;gt;
        &amp;lt;/div&amp;gt;
        &amp;lt;input type=&quot;submit&quot; name=&quot;submit&quot; id=&quot;ava_submit&quot; value=&quot;Crop&quot; style=&quot;width: auto; font-size: 105%; font-weight: bold; margin: 1em 0;&quot; /&amp;gt;
    &amp;lt;/form&amp;gt;
&amp;lt;/div&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Right now a lot of this doesn't quite make sense.  If you attempt to render it, you will just see only the image.  As we add the corresponding &lt;acronym title=&quot;Cascading Style Sheets&quot;&gt;CSS&lt;/acronym&gt; and images it will make some more sense.&lt;/p&gt;

&lt;h4&gt;&lt;acronym title=&quot;Cascading Style Sheets&quot;&gt;CSS&lt;/acronym&gt; and corresponding images&lt;/h4&gt;

&lt;p&gt;We'll go through each style individually and explain what purpose it serves in terms of the &lt;acronym title=&quot;Graphical User Interface&quot;&gt;GUI&lt;/acronym&gt;.&lt;/p&gt;

&lt;p&gt;&lt;code&gt;#ava&lt;/code&gt; is our container.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#ava {
    border: 1px solid gray;
     width: 200px;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;#ava_img&lt;/code&gt; is the area that contains our image.  Our window for editing this image 200x200 pixels.  If we drag out image out of bounds we just want the overflowing image to be clipped.  We also want our position to be relative so any child elements can be positioned absolutely with respect to &lt;code&gt;#ava_img&lt;/code&gt;.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#ava_img {
    width: 200px;
    height: 200px;
    overflow: hidden;
    position: relative;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;div style=&quot;float:left;margin: 1em 1em 1em 0&quot;&gt;
    &lt;img src=&quot;http://demos.spindrop.us/image_cropper/images/overlay.png&quot; alt=&quot;overlay&quot; /&gt;
&lt;/div&gt;


&lt;p&gt;&lt;code&gt;#ava_overlay&lt;/code&gt; is a window we use to see what exactly will be our avatar.  If it's in the small 80x80 window in the center of the image, then it's part of the avatar.  If it's in the fuzzy region, then it's getting cropped out.  This overlay of course needs to be positioned absolutely.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#ava_overlay {
    width: 200px;
    height: 200px;
    position: absolute;
    top: 0px;
    left: 0px;
    background: url('/images/overlay.png');
    z-index: 50;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;#ava_drager&lt;/code&gt; is probably the least intuitive element (Heck, I'm not even sure if I've even got it right).  In &lt;a href=&quot;http://demos.spindrop.us/image_cropper/&quot;&gt;our demo&lt;/a&gt; you're not actually dragging the image, because you can drag anywhere within the &lt;code&gt;#ava_img&lt;/code&gt; container and move the image around.  You're using dragging an invisible handle.  It's a 400x400 pixel square that can be dragged all over the container and thusly move the image as needed.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#ava_drager {
    width: 400px;
    height: 400px;
    position: absolute;
    z-index: 100;
    color: #fff;
    cursor: move;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;#avatar&lt;/code&gt; is our image, and since it will be moving all around the window, it requires absolute positioning.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#avatar {
    position: absolute;
}
&lt;/code&gt;&lt;/pre&gt;

&lt;div style=&quot;float:left;margin: 1em 1em 1em 0&quot;&gt;
    &lt;img src=&quot;http://demos.spindrop.us/image_cropper/images/slider_back.png&quot; alt=&quot;overlay&quot; /&gt;
&lt;/div&gt;


&lt;div style=&quot;float:left;margin-left: 1em 1em 1em 0;&quot;&gt;
    &lt;img src=&quot;http://demos.spindrop.us/image_cropper/images/handle.png&quot; alt=&quot;overlay&quot; /&gt;
&lt;/div&gt;


&lt;p&gt;&lt;code&gt;#ava_slider&lt;/code&gt; and &lt;code&gt;#ava_handle&lt;/code&gt; are our slider components.  They should be self-explanatory.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#ava_slider {
    width: 200px;
    height: 27px;
    background: #eee;
    position: relative;
    border-top: 1px solid gray; 
    background: url('/images/slider_back.png');
}
#ava_handle {
    width: 19px;
    height: 20px;
    background: blue;
    position: absolute;
    background: url('/images/handle.png');
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h5&gt;Internet Explorer&lt;/h5&gt;

&lt;p&gt;&lt;acronym title=&quot;Portable Network Graphics&quot;&gt;PNG&lt;/acronym&gt; do not work so well in Internet Explorer, but there is a small trick, adding these components into a style sheet that only IE can read will make things work:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;#ava_overlay {
  background: none;
  filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/images/ui/cropper/overlay.png', sizingMethod='crop');
}

#ava_handle {
  background: none;
  filter:progid:DXImageTransform.Microsoft.AlphaImageLoader(src='/images/ui/cropper/handle.png', sizingMethod='crop');
}
&lt;/code&gt;&lt;/pre&gt;

&lt;h4&gt;The Javascript&lt;/h4&gt;

&lt;p&gt;The Javascript is actually not as complicated as you'd expect thanks to the wonder of &lt;a href=&quot;http://prototype.conio.net/&quot;&gt;prototype&lt;/a&gt;.  This framework provides so much so easily.  You'll need to include &lt;a href=&quot;http://prototype.conio.net/&quot;&gt;prototype.js&lt;/a&gt; and &lt;a href=&quot;http://boring.youngpup.net/2001/domdrag/project&quot;&gt;dom-drag.js&lt;/a&gt;.&lt;/p&gt;

&lt;p&gt;So let's take a look.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;&amp;lt;script type=&quot;text/javascript&quot; language=&quot;javascript&quot; charset=&quot;utf-8&quot;&amp;gt;
// &amp;lt;![CDATA[
function setupAva() {
    if ($(&quot;avatar&quot;)) {
        var handle = $(&quot;ava_handle&quot;);
        var avatar = $(&quot;avatar&quot;);
        var drager = $(&quot;ava_drager&quot;);
        var slider = $(&quot;ava_slider&quot;);
        var ava_width = $(&quot;ava_width&quot;);
        var ava_x = $(&quot;ava_x&quot;);
        var ava_y = $(&quot;ava_y&quot;);
        // four numbers are minx, maxx, miny, maxy
        Drag.init(handle, null, 0, 134, 0, 0);
        Drag.init(drager, avatar, -100, 350, -100, 350);
        var start_w = avatar.width;
        var start_h = avatar.height;
        var ratio = (start_h / start_w);
        var new_h;
        var new_w;
        if (ratio &amp;gt; 1) {
            new_w = 80;
            new_h = (80*start_h)/start_w;
        } else {
            new_h = 80;
            new_w = (80*start_w)/start_h;
        }
        // these need to be set after we init
        avatar.style.top = '100px';
        avatar.style.left = '100px';
        avatar.style.width = new_w + 'px';
        avatar.style.height = new_h + 'px';
        avatar.style.margin = '-' + (new_h / 2) + 'px 0 0 -' + (new_w / 2) + 'px';
        handle.style.margin = '3px 0 0 20px';
        avatar.onDrag = function(x, y) {
            ava_x.value = x;
            ava_y.value = y;
        }
        handle.onDrag = function(x, y) {
            var n_width = (new_w + (x * 2));
            var n_height = (new_h + ((x * 2) * ratio));         
            avatar.style.width = n_width + 'px';
            avatar.style.height = n_height+ 'px';
            ava_width.value = n_width;  
            avatar.style.margin = '-' + (n_height / 2) + 'px 0 0 -' + (n_width / 2) + 'px';
        }
    }
}
Event.observe(window,'load',setupAva, false);
// ]]&amp;gt;
&amp;lt;/script&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;If this isn't exactly crystal clear, I can explain.  If you're new to &lt;a href=&quot;http://prototype.conio.net/&quot;&gt;prototype&lt;/a&gt;, &lt;code&gt;$()&lt;/code&gt; is the same as &lt;code&gt;doucment.getElementByID()&lt;/code&gt; (at least for our purposes).&lt;/p&gt;

&lt;p&gt;We need to initialize two draggable elements, one is our slider for zooming and the other is our avatar itself.  We initialize the draggers using &lt;code&gt;Drag.init()&lt;/code&gt;.  We specify what to drag, if another element should be used as a handle and then the range of motion in xy coordinates.  In the second call we use that &lt;code&gt;#dragger&lt;/code&gt; to move around the image in this manner.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;Drag.init(handle, null, 0, 134, 0, 0);
Drag.init(drager, avatar, -100, 350, -100, 350);
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We want to initialize the the size and placement of the avatar.  We do that using maths.  First we want it in our 80x80 pixel box.  So it should be roughly 80x80.  I've set the math up so that the &lt;em&gt;smallest&lt;/em&gt; side is 80 pixels (there's reasons for doing this the other way around).&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    if (ratio &amp;gt; 1) {
        new_w = 80;
        new_h = (80*start_h)/start_w;
    } else {
        new_h = 80;
        new_w = (80*start_w)/start_h;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We then place the avatar element.  We initialize it to be in the center of the screen (&lt;code&gt;top: 100px;left:100px&lt;/code&gt;) and then nudge the image using margins.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    avatar.style.top = '100px';
    avatar.style.left = '100px';
    avatar.style.width = new_w + 'px';
    avatar.style.height = new_h + 'px';
    avatar.style.margin = '-' + (new_h / 2) + 'px 0 0 -' + (new_w / 2) + 'px';
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We also use margins to place the handle.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    handle.style.margin = '3px 0 0 20px';
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;&lt;code&gt;#ava_x&lt;/code&gt; and &lt;code&gt;#ava_y&lt;/code&gt; tell us where the center of the avatar is.  So when the avatar is moved we need to set these again:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    avatar.onDrag = function(x, y) {
        ava_x.value = x;
        ava_y.value = y;
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;That was easy.  Slighly more complicated is the zoomer function.  We are basically adjusting the width and the height proportionately based on roughly where the slider is.  Note that we're still using that &lt;code&gt;ratio&lt;/code&gt; variable that we calculated earlier.  We basically take the new x-coordinate of the handle and allow our image to get just slightly larger than the &lt;code&gt;#ava_image&lt;/code&gt; container.&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;    handle.onDrag = function(x, y) {
        var n_width = (new_w + (x * 2));
        var n_height = (new_h + ((x * 2) * ratio));         
        avatar.style.width = n_width + 'px';
        avatar.style.height = n_height+ 'px';
        ava_width.value = n_width;  
        avatar.style.margin = '-' + (n_height / 2) + 'px 0 0 -' + (n_width / 2) + 'px';
    }
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We want to load initialize the slider right away when the page loads: &lt;code&gt;Event.observe(window,'load',setupAva, false);&lt;/code&gt;&lt;/p&gt;

&lt;p&gt;Not terribly hard or complicated.  Once these elements are all in place you have a working functioning slider.  It returns the x and y coordinates of the center of the image with respect to our 200x200 pixel &lt;code&gt;#ava_image&lt;/code&gt;.  It also tells us the new width of our image.  We feed this information into a new script and out should pop a new image which matches &lt;em&gt;exactly&lt;/em&gt; what we see in our &lt;acronym title=&quot;Graphical User Interface&quot;&gt;GUI&lt;/acronym&gt;.&lt;/p&gt;

&lt;!--nextpage--&gt;


&lt;h3&gt;Processing the crop&lt;/h3&gt;

&lt;p&gt;Initially I was frustrated with the data that was being sent.  I knew the center of the image in relation to this 200x200 pixel canvas and its width... but what could I do with that.  Well I could just recreate what I saw in the &lt;acronym title=&quot;Graphical User Interface&quot;&gt;GUI&lt;/acronym&gt;.  I needed to create a 200x200 pixel image first, place my original avatar resized (and resampled) at the precise coordinates and &lt;em&gt;then&lt;/em&gt; cut out the center most 80x80 pixels to become the final avatar image.&lt;/p&gt;

&lt;p&gt;If you note in our template above for &lt;code&gt;cropSuccess.php&lt;/code&gt; we submit our form back to the &lt;code&gt;crop&lt;/code&gt; action.  Let's look at the action:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public function executeCrop()
{
    if ($this-&amp;gt;getRequestParameter('file')&amp;amp;&amp;amp;$this-&amp;gt;getRequestParameter('width')) {          // we are saving our cropped image
        // Load the original avatar into a GD image so we can manipulate it with GD
        $o_filename = $this-&amp;gt;getRequestParameter('file');  // we'll use this to find the file on our system
        $o_filename = sfConfig::get('sf_root_dir').'/web' . $o_filename;
        $o_im = @imagecreatetruecolor(80, 80) or die(&quot;Cannot Initialize new GD image stream&quot;);
        $o_imagetype = exif_imagetype($o_filename); // is this gif/jpeg/png

        // appropriately create the GD image
        switch ($o_imagetype) {
            case 1: // gif
                $o_im = imagecreatefromgif($o_filename);
                break;
            case 2: // jpeg
                $o_im = imagecreatefromjpeg($o_filename);   
                break;
            case 3: // png
                $o_im = imagecreatefrompng($o_filename);
                break;
        }

        // Let's create our canvas
        $im = @imagecreatetruecolor(200, 200) or die(&quot;Cannot Initialize new GD image stream&quot;);
        imagecolortransparent ( $im, 127 ); // set the transparency color to 127
        imagefilledrectangle( $im, 0, 0, 200, 200, 127 ); // fill the canvas with a transparent rectangle

        // let's get the new dimension for our image

        $new_width = $this-&amp;gt;getRequestParameter('width');
        $o_width = imageSX($o_im);
        $o_height = imageSY($o_im);

        $new_height = $o_height/$o_width * $new_width;

        // we place the image at the xy coordinate and then shift it so that the image is now centered at the xy coordinate
        $x = $this-&amp;gt;getRequestParameter('x') - $new_width/2;
        $y = $this-&amp;gt;getRequestParameter('y') - $new_height/2;

        // copy the original image resized and resampled onto the canvas
        imagecopyresampled($im,$o_im,$x,$y,0,0,$new_width,$new_height,$o_width,$o_height); 
        imagedestroy($o_im);

        // $final will be our final image, we will chop $im and take out the 80x80 center
        $final = @imagecreatetruecolor(80, 80) or die(&quot;Cannot Initialize new GD image stream&quot;);
        imagecolortransparent ( $final, 127 ); // maintain transparency

        //copy the center of our original image and store it here
        imagecopyresampled ( $final, $im, 0, 0, 60, 60, 80, 80, 80, 80 );
        imagedestroy($im);

        //save our new user pic
        $p = new Userpic();
        $p-&amp;gt;setUser($this-&amp;gt;getUser()-&amp;gt;getUser());
        $p-&amp;gt;setGD2($final);
        $p-&amp;gt;save();
        imagedestroy($final);
        $this-&amp;gt;userpic = $p;
        return &quot;Finished&quot;;
    }


    $this-&amp;gt;getResponse()-&amp;gt;addJavascript(&quot;dom-drag&quot;);
    $this-&amp;gt;getResponse()-&amp;gt;addJavascript('/sf/js/prototype/prototype');
    $this-&amp;gt;getResponse()-&amp;gt;addJavascript('/sf/js/prototype/effects');
    $this-&amp;gt;image = '/images/userpics/originals/' . $this-&amp;gt;getRequestParameter('file');
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;It's doing exactly what the paragraph above explains when the image dimensions are given.  The code is well commented so it should be easy enough to follow.&lt;/p&gt;

&lt;p&gt;&lt;a href=&quot;http://www.php.net/manual/en/ref.image.php&quot;&gt;GD image functions in PHP&lt;/a&gt; are fairly robust and can help you do a lot of tricks with image data.  Note the code to save the image, we'll cover it in detail soon.&lt;/p&gt;

&lt;h3&gt;The Model&lt;/h3&gt;

&lt;pre&gt;&lt;code&gt;$p = new Userpic();
$p-&amp;gt;setUser($this-&amp;gt;getUser()-&amp;gt;getUser());
$p-&amp;gt;setGD2($final);
$p-&amp;gt;save();
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;First some clarification the second line.  &lt;code&gt;myUser::getUser()&lt;/code&gt; gets the &lt;code&gt;User&lt;/code&gt; object associated with the currently logged in user.  The third line, however, is where the magic happens.  Before we look at it, let's have a quick look at our model:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;userpic:
 _attributes: { phpName: Userpic }
 id:
 user_id:
 image: blob
 thumb: blob
 created_at:
 updated_at:
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We have an &lt;code&gt;image&lt;/code&gt; attribute and a &lt;code&gt;thumb&lt;/code&gt; property to our &lt;code&gt;Userpic&lt;/code&gt; object.  This is where we store &lt;acronym title=&quot;Portable Network Graphics&quot;&gt;PNG&lt;/acronym&gt; versions of each icon and their 16x16 thumbnails respectively.  We do this in &lt;code&gt;Userpic::setGD2()&lt;/code&gt;:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;public function setGD2($gd2_image)
{
    //convert to PNG
    ob_start();
    imagepng($gd2_image);
    $png = ob_get_clean();
    //save 16x16
    $gd2_tn = @imagecreatetruecolor(16, 16) or die(&quot;Cannot Initialize new GD image stream&quot;);
    imagealphablending( $gd2_tn, true );
    imagecolortransparent ( $gd2_tn, 127 );

    imagecopyresampled ( $gd2_tn, $gd2_image, 0, 0, 0, 0, 16, 16, 80, 80 );
    ob_start();
    imagepng($gd2_tn);
    $tn = ob_get_clean();

    $this-&amp;gt;setImage($png);
    $this-&amp;gt;setThumb($tn);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;We capture the output of the full size &lt;acronym title=&quot;Portable Network Graphics&quot;&gt;PNG&lt;/acronym&gt;, then we scale it again and capture the output of the thumbnail and set them.&lt;/p&gt;

&lt;h3&gt;Conclusion&lt;/h3&gt;

&lt;p&gt;When it comes to web apps, having a relatively simple &lt;acronym title=&quot;Graphical User Interface&quot;&gt;GUI&lt;/acronym&gt; for people to resize images can go a long way in terms of adoption rate of avatars and custom user pictures by non technical users.&lt;/p&gt;

&lt;p&gt;Enjoy, and if you found this useful (or better implemented it) let me know.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Inverting color codes in Textmate</title>
   <link href="http://davedash.com/2006/07/19/inverting-color-codes-in-textmate/"/>
   <updated>2006-07-19T00:00:00-07:00</updated>
   <id>http://davedash.com/2006/07/19/inverting-color-codes-in-textmate</id>
   <content type="html">&lt;p&gt;I deal a lot with &lt;abbr title=&quot;hexadecimal&quot;&gt;hex&lt;/abbr&gt; color codes in &lt;acronym title=&quot;Cascading Style Sheets&quot;&gt;CSS&lt;/acronym&gt;.  One thing I occasionally need to do is invert color codes.  Normally this is something I could &lt;a href=&quot;http://www.google.com/search?q=inverse+colors+hex&quot;&gt;Google&lt;/a&gt; for, but I wanted a solution that didn't requiring constant reference.&lt;/p&gt;

&lt;p&gt;My favorite text editor, &lt;a href=&quot;http://macromates.com/&quot;&gt;Textmate&lt;/a&gt;, has a powerful automation system.  I can write mini scripts in whatever language suitable and take advantage of the power of Unix shell scripting to execute them.  &lt;a href=&quot;http://www.google.com/search?q=inverse+colors+hex&quot;&gt;From Googling&lt;/a&gt;, I learned enough ruby to learn that this:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;printf(&quot;#%06X&quot;, 0xFFFFFF - STDIN.gets.gsub(/^#/,&quot;&quot;).hex )
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Will invert a hex color from standard input.  What it's doing is fairly simple.  It's using &lt;code&gt;printf&lt;/code&gt; to print a formatted string.  &lt;code&gt;%06X&lt;/code&gt; means it should zero-fill the resulting string with up to six zeros, the same way a hex color string is (e.g. we write 0000FF and not FF to mean 'blue').  The rest is simple subtraction.  We take &lt;code&gt;FFFFFF&lt;/code&gt;, the hex code for white, and subtract the input from &lt;code&gt;STDIN&lt;/code&gt; and arrive at the inverse of what we started.&lt;/p&gt;

&lt;!--next page--&gt;


&lt;p&gt;Now to add this to &lt;a href=&quot;http://macromates.com/&quot;&gt;TextMate&lt;/a&gt; we open &lt;code&gt;Automation|Run Command|Edit Commands...&lt;/code&gt; and create a new command:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;echo $TM_SELECTED_TEXT |ruby -e 'printf(&quot;#%06X&quot;, 0xFFFFFF - STDIN.gets.gsub(/^#/,&quot;&quot;).hex )' 
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This echo's whatever is selected and pipes it to the &lt;code&gt;ruby&lt;/code&gt; script.  We set the command to input selected text and replace the selected text on output.  Furthermore we can bind it to a keystroke.  I chose &lt;code&gt;Control-Alt-I&lt;/code&gt;, as it is unused on my system.&lt;/p&gt;

&lt;p&gt;Voila, I can highlight any hex code and instantly invert it.&lt;/p&gt;

&lt;p&gt;To keep this on one line, I neglected a few friendly features.  One is interpreting 3-digit &lt;abbr title=&quot;hexadecimal&quot;&gt;hex&lt;/abbr&gt; colors (e.g. #ccc), and the other is knowing whether or not to place the &lt;code&gt;#&lt;/code&gt; in the result.  If you can come up with an elegant solution, please post it below.  Otherwise I hope this helps.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Safari Fixes</title>
   <link href="http://davedash.com/2006/07/11/safari-fixes/"/>
   <updated>2006-07-11T00:00:00-07:00</updated>
   <id>http://davedash.com/2006/07/11/safari-fixes</id>
   <content type="html">&lt;p&gt;Safari interprets &lt;code&gt;/* */&lt;/code&gt;s differently than FireFox or &lt;acronym title=&quot;Internet Explorer&quot;&gt;IE&lt;/acronym&gt;.  &lt;acronym title=&quot;FireFox&quot;&gt;FF&lt;/acronym&gt; and &lt;acronym title=&quot;Internet Explorer&quot;&gt;IE&lt;/acronym&gt; will ignore a unmatched &lt;code&gt;/*&lt;/code&gt; or &lt;code&gt;*/&lt;/code&gt;, whereas Safari will ignore parts of code if there's a lone &lt;code&gt;*/&lt;/code&gt;.  Once I found that out, I was able to get the list items that are used throughout the site to render properly.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Breaking IE 6 with links on PNG backgrounds</title>
   <link href="http://davedash.com/2006/06/27/breaking-ie-6-with-links-on-png-backgrounds/"/>
   <updated>2006-06-27T00:00:00-07:00</updated>
   <id>http://davedash.com/2006/06/27/breaking-ie-6-with-links-on-png-backgrounds</id>
   <content type="html">&lt;p&gt;In &lt;acronym title=&quot;Internet Explorer&quot;&gt;IE&lt;/acronym&gt; there's a whole slew of troubles with &lt;acronym title=&quot;Portable Network Graphics&quot;&gt;PNG&lt;/acronym&gt;.  One such trouble is links or anchors will not work in &lt;acronym title=&quot;Internet Explorer&quot;&gt;IE&lt;/acronym&gt; if you have a &lt;acronym title=&quot;Portable Network Graphics&quot;&gt;PNG&lt;/acronym&gt; image that has gone through the Microsoft &lt;code&gt;[AlphaImageLoader]&lt;/code&gt;, which is the only known way to render &lt;acronym title=&quot;Portable Network Graphic&quot;&gt;PNG&lt;/acronym&gt;s in &lt;acronym title=&quot;Internet Explorer&quot;&gt;IE&lt;/acronym&gt;6.&lt;/p&gt;

&lt;p&gt;The solution, involves running the image filter on a separate element, and then positioning all the links within that element in a higher z-order.  This is explained in better detail in &lt;a href=&quot;http://www.satzansatz.de/cssd/tmp/alphatransparency.html&quot;&gt;Filter Flaws&lt;/a&gt;.&lt;/p&gt;

&lt;!--more--&gt;


&lt;p&gt;I've been running into too many designers who have been sending me too many designs that require translucent layers, and alpha-transparencies (and they should be able to, even though the trend is more simple these days).  This of course subjects me to pretty much any strange quirk that &lt;acronym title=&quot;Internet Explorer&quot;&gt;IE&lt;/acronym&gt;6 can dish out with &lt;acronym title=&quot;Portable Network Graphic&quot;&gt;PNG&lt;/acronym&gt;s.&lt;/p&gt;

&lt;p&gt;What's frustrating is that &lt;a href=&quot;http://davedash.com/2001/10/16/png_and_internet_explorer/&quot;&gt;5 years ago&lt;/a&gt; I had &lt;acronym title=&quot;Portable Network Graphic&quot;&gt;PNG&lt;/acronym&gt;s problems.  This is the Internet... very few problems on the Internet last that long.  There's certainly been enough people complaining about this malfunction in &lt;acronym title=&quot;Internet Explorer&quot;&gt;IE&lt;/acronym&gt; for years.&lt;/p&gt;

&lt;p&gt;The problem with these problems is there is no &quot;right&quot; solution.  Using &lt;code&gt;[AlphaImageLoader]&lt;/code&gt; is a hack.  As we can see with laying links upon backgrounds that use the loader, it's prone to behavior we don't normally expect.  We shouldn't have to raise the links above an invisible layer, in order to click on them.&lt;/p&gt;

&lt;p&gt;Unfortunately as long as the majority of our users continue to use &lt;acronym title=&quot;Internet Explorer&quot;&gt;IE&lt;/acronym&gt; 6 (or older) we'll be stuck with this problem.  If we look at &lt;a href=&quot;http://www.christopherschmitt.com/2006/04/12/adoption-rate-of-internet-explorer-7/&quot;&gt;adoption rates&lt;/a&gt; it won't be until a year after Internet Explorer 7 is out until it's the top dog.  Even then, if Firefox is still at 10% marketshare, that leaves another 40% with &lt;acronym title=&quot;Internet Explorer&quot;&gt;IE&lt;/acronym&gt;6 (or less) and the less popular browsers.  We're still stuck with this problem for some time.&lt;/p&gt;
</content>
 </entry>
 
 <entry>
   <title>Editing CSS live in Firefox</title>
   <link href="http://davedash.com/2006/06/02/editing-css-live-in-firefox/"/>
   <updated>2006-06-02T00:00:00-07:00</updated>
   <id>http://davedash.com/2006/06/02/editing-css-live-in-firefox</id>
   <content type="html">&lt;h3&gt;Summary&lt;/h3&gt;

&lt;p&gt;&lt;code&gt;Firefox + Web Developer Extension = Live CSS Editing&lt;/code&gt; if that makes sense to you, you probably don't need to read on any further, except perhaps the &quot;caveats&quot; section.&lt;/p&gt;

&lt;p&gt;Trusting a &lt;acronym title=&quot;What You See Is What You Get&quot;&gt;WYSIWYG&lt;/acronym&gt; editor for &lt;acronym title=&quot;Cascading Style Sheets&quot;&gt;CSS&lt;/acronym&gt; can be quite inaccurate and after viewing a site within &lt;a href=&quot;http://www.getfirefox.com/&quot;&gt;Firefox&lt;/a&gt; and &lt;acronym title=&quot;Internet Explorer&quot;&gt;IE&lt;/acronym&gt; it can be quite different than intended.  This leads &lt;acronym title=&quot;Cascading Style Sheets&quot;&gt;CSS&lt;/acronym&gt; developers into the Edit&amp;rarr;Save&amp;rarr;Reload&amp;rarr;repeat&amp;#8617; cycle.&lt;/p&gt;

&lt;p&gt;What if you could edit the &lt;acronym title=&quot;Cascading Style Sheets&quot;&gt;CSS&lt;/acronym&gt; that &lt;a href=&quot;http://www.getfirefox.com/&quot;&gt;Firefox&lt;/a&gt; is using without having to go through this cycle?&lt;/p&gt;

&lt;!--more--&gt;


&lt;h3&gt;Firefox and the Web Developer Extension&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://www.getfirefox.com/&quot;&gt;Firefox&lt;/a&gt;'s saving grace is the support for extensions.&lt;sup id=&quot;fnr1&quot;&gt;&lt;a href=&quot;#fn1&quot;&gt;1&lt;/a&gt;&lt;/sup&gt;  There's a few extensions that appear on just about everyone's top ten list of extensions for Firefox (&lt;a href=&quot;http://www.themoleskin.com/archives/10-firefox-extensions-for-web-development/&quot;&gt;here's one list&lt;/a&gt;).  Chris Pederick's &lt;a href=&quot;http://chrispederick.com/work/webdeveloper/&quot;&gt;Web Developer Extension&lt;/a&gt; is one of those.  Use it to manipulate cookies, style sheets, forms, images as well as get helpful information about the web page.&lt;/p&gt;

&lt;h3&gt;Editing &lt;acronym title=&quot;Cascading Style Sheets&quot;&gt;CSS&lt;/acronym&gt;&lt;/h3&gt;

&lt;p&gt;The way I use &lt;acronym title=&quot;Cascading Style Sheets&quot;&gt;CSS&lt;/acronym&gt; is by writing &lt;a href=&quot;http://www.contentwithstyle.co.uk/Articles/106/&quot;&gt;semantic HTML&lt;/a&gt; and then individually styling elements of my site.  Sure a lot can be done without having to look at a page.  If I want to mimic this site, I can try for:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;body {
         color: white;
    background: #333;
}

h2 { 
    color: #f6861a; /* orange */
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;Depending on how imaginative you are, you can get quite far without viewing a page.  Now, however, you can just open up your unstyled page, select &lt;code&gt;Edit CSS&lt;/code&gt; under the &lt;code&gt;CSS&lt;/code&gt; menu of the &lt;a href=&quot;http://chrispederick.com/work/webdeveloper/&quot;&gt;Web Developer Extension&lt;/a&gt; and &lt;strong&gt;see&lt;/strong&gt; the changes &lt;em&gt;as you make them&lt;/em&gt;.  You can throw Dreamweaver out.  This is what you really need.&lt;/p&gt;

&lt;p&gt;The greatest advantage of this is if you need to do pixel moving.  Let's say you have a complicated layout with absolutely positioned &lt;code&gt;div&lt;/code&gt;s.  Now you can move them a pixel at a time until they look &lt;em&gt;just&lt;/em&gt; right.&lt;/p&gt;

&lt;h3&gt;Caveat&lt;/h3&gt;

&lt;p&gt;One major hang-up that I have with the &lt;code&gt;Edit CSS&lt;/code&gt; feature is that it breaks relative references if you use &lt;code&gt;url()&lt;/code&gt;.  For example.  Let's say you have a &lt;code&gt;/theme&lt;/code&gt; folder for your web site's theme.  Under the &lt;code&gt;/theme&lt;/code&gt; you have &lt;code&gt;theme.css&lt;/code&gt; and &lt;code&gt;background.png&lt;/code&gt;.  In &lt;code&gt;theme.css&lt;/code&gt; you have:&lt;/p&gt;

&lt;pre&gt;&lt;code&gt;body {
    background: url(background.png);
}
&lt;/code&gt;&lt;/pre&gt;

&lt;p&gt;This will work fine, &lt;code&gt;url()&lt;/code&gt; is relative to the file containing the &lt;acronym title=&quot;Cascading Style Sheet&quot;&gt;CSS&lt;/acronym&gt;.  When you go to &lt;code&gt;Edit CSS&lt;/code&gt;, however, the relativity is broken, because &lt;code&gt;Edit CSS&lt;/code&gt; adds the &lt;acronym title=&quot;Cascading Style Sheets&quot;&gt;CSS&lt;/acronym&gt; to the currently viewed document.  Therefore unless your &lt;acronym title=&quot;Cascading Style Sheets&quot;&gt;CSS&lt;/acronym&gt; is in the same directory as your web page, anything relatively linked with &lt;code&gt;url()&lt;/code&gt; is broken.&lt;/p&gt;

&lt;p&gt;If this is a show stopper for you, use absolute references whenever possible.  Of course with themed sites, this is often not possible.  I'm sure someone clever can make some changes to this extension to fix it.&lt;/p&gt;

&lt;h3&gt;What about Internet Explorer&lt;/h3&gt;

&lt;p&gt;This method does leave out &lt;acronym title=&quot;Internet Explorer&quot;&gt;IE&lt;/acronym&gt;.  You will still need to do some back and forth when looking at &lt;acronym title=&quot;Internet Explorer&quot;&gt;IE&lt;/acronym&gt;.  There are a few things that can alleviate this process.&lt;/p&gt;

&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Use standards compliance mode.&lt;/strong&gt;  Having a similar enough box-model to work with will eliminate most of the differences noted in &lt;acronym title=&quot;Internet Explorer&quot;&gt;IE&lt;/acronym&gt; and &lt;a href=&quot;http://www.getfirefox.com/&quot;&gt;Firefox&lt;/a&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Know the problem areas.&lt;/strong&gt;  There's a few spots in &lt;acronym title=&quot;Internet Explorer&quot;&gt;IE&lt;/acronym&gt; that are problem areas.  &lt;acronym title=&quot;Portable Network Graphics&quot;&gt;PNG&lt;/acronym&gt; is one, negative margins are another.  If you know what they are, then when you use them you'll be aware that you'll need to adjust them for &lt;acronym title=&quot;Internet Explorer&quot;&gt;IE&lt;/acronym&gt;.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;If you use hacks use the same ones.&lt;/strong&gt; If you use a &quot;hack&quot; to make &lt;acronym title=&quot;Internet Explorer&quot;&gt;IE&lt;/acronym&gt; cooperate, try sticking to the same hack.  It makes your code easier to read, and consistancy makes life a bit easier.&lt;/li&gt;
&lt;/ul&gt;


&lt;p&gt;If you do all that, you'll probably still save quite a bit of time in your &lt;acronym title=&quot;Cascading Style Sheets&quot;&gt;CSS&lt;/acronym&gt; development.&lt;/p&gt;

&lt;h3&gt;CSS Vista&lt;/h3&gt;

&lt;p&gt;&lt;a href=&quot;http://www.sitevista.com/cssvista/&quot;&gt;CSS Vista&lt;/a&gt; is a promising product.  I tried it out recently (May 2006) and decided it isn't stable enough to be useful.  I would like it to be more integrated with &lt;acronym title=&quot;Internet Explorer&quot;&gt;IE&lt;/acronym&gt; as well as be a lot faster.  I'm sure when they release 0.2, the stability will improve.  It may have been a fluke with my laptop as well.  Try it out, it might be able to be a good solution for Internet Explorer (and &lt;a href=&quot;http://www.getfirefox.com/&quot;&gt;Firefox&lt;/a&gt;).  Unfortunately it's Windows only.&lt;/p&gt;

&lt;div id=&quot;footnotes&quot;&gt;
    &lt;hr /&gt;
    &lt;ol&gt;
        &lt;li id=&quot;fn1&quot;&gt;In a heartbeat I would switch to Camino or Safari if they supported such a wide array of extensions. &lt;a href=&quot;#fnr1&quot; class=&quot;footnoteBackLink&quot;  title=&quot;Jump back to footnote 1 in the text.&quot;&gt;&amp;#8617;&lt;/a&gt;&lt;/li&gt;
    &lt;/ol&gt;
&lt;/div&gt;

</content>
 </entry>
 
 <entry>
   <title>AJAX star rater for symfony</title>
   <link href="http://davedash.com/2006/05/23/ajax-star-rater-for-symfony/"/>
   <updated>2006-05-23T00:00:00-07:00</updated>
   <id>http://davedash.com/2006/05/23/ajax-star-rater-for-symfony</id>
   <content type="html">&lt;p&gt;Francois from the &lt;a href=&quot;http://www.symfony-project.com/&quot;&gt;symfony project&lt;/a&gt; beat me to the punch.  I was going to post a detailed how-to on adding a star-rater to your web site (similar to the &lt;a href=&quot;http://spindrop.us/2006/05/17/rate-your-favorite-dishes&quot;&gt;one's I created for reviewsby.us&lt;/a&gt;), but for most of you &lt;a href=&quot;http://www.symfony-project.com/snippets/5&quot;&gt;this should do the trick&lt;/a&gt;.  Unless people request it sooner, I'll hold off on publishing the details on my star-rater for a while.  It only offers a few minor differences (&lt;acronym title=&quot;In My Opinion&quot;&gt;IMO&lt;/acronym&gt; advantages) to this snippet.&lt;/p&gt;
</content>
 </entry>
 

</feed>

