<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>richwklein.com &#187; Work</title>
	<atom:link href="http://richwklein.com/category/work/feed/" rel="self" type="application/rss+xml" />
	<link>http://richwklein.com</link>
	<description>A blog about nothing</description>
	<lastBuildDate>Tue, 05 Apr 2011 02:07:01 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.1</generator>
	<atom:link rel='hub' href='http://richwklein.com/?pushpress=hub'/>
		<item>
		<title>Python List Filter Helper</title>
		<link>http://richwklein.com/2011/01/13/python-list-filter-helper/</link>
		<comments>http://richwklein.com/2011/01/13/python-list-filter-helper/#comments</comments>
		<pubDate>Thu, 13 Jan 2011 19:22:14 +0000</pubDate>
		<dc:creator>Rich</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Filter]]></category>
		<category><![CDATA[GAE]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Google App Engine]]></category>
		<category><![CDATA[Helper]]></category>
		<category><![CDATA[List]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Tip]]></category>
		<category><![CDATA[Trick]]></category>

		<guid isPermaLink="false">http://richwklein.com/?p=1827</guid>
		<description><![CDATA[In a previous post, I mentioned I&#8217;ve been doing a lot of datagrid work lately. In addition to column sorting another feature I&#8217;ve added is the filtering of the datagrid by a specific value in a column. Most of these columns contain string values that we can use the same logic on, over and over [...]]]></description>
			<content:encoded><![CDATA[<p>In a <a href="http://richwklein.com/2011/01/06/python-in-memory-sort-helper/">previous post</a>, I mentioned I&#8217;ve been doing a lot of datagrid work lately.  In addition to column sorting another feature I&#8217;ve added is the filtering of the datagrid by a specific value in a column.  Most of these columns contain string values that we can use the same logic on, over and over again.  I&#8217;ve come up with a helper function that generalizes the string filtering and can be used for this.  The helper does a couple of special things.
<ul>
<li>It allows you to filter by returned values of object methods.</li>
<li>It searches for the term anywhere in the value.</li>
<li>It does a case in-sensitive search.</li>
<li>It does some basic value clean up.</li>
</ul>
<p><span id="more-1827"></span><br />
The code is commented fairly extensively so you should be able to figure out what I’m doing.</p>
<pre>
import re

FILTER_RE = re.compile('[-[\]{}()*+?.,\\^$|#\s]')
REPLACE_WITH = ''
def filter_helper(object_list, attr, term):
    """
    Helper method for filtering object_lists.

    @param  object_list     An array of objects to filter.
    @param  attr            An attribute on the object to filter the list by.
    @param  term            The filter term to look for in the attribute.
    @return The filtered list
    """

    # remove special characters from the filter term
    escaped_term = FILTER_RE.sub(REPLACE_WITH, term)

    def compare(x):
        """
        Function that compares the value to the filter term.

        @param  x    The object we are looking at.
        @return True if we have a match otherwise False.
        """

        # get the attribute off the object
        v = getattr(x, attr)

        # attribute is a method so get the return value
        if callable(v): v = v()

        # remove special characters from the attribute value
        ev = FILTER_RE.sub(REPLACE_WITH, v)

        # if the term is an exact match or the escaped term is in the escaped attr
        if term == v or re.search(escaped_term, ev, re.I):
            return True
        return False

    # run the compare function through the list to create the filtered list
    return filter(compare, object_list)
</pre>
<p>To use the helper you would do something like:</p>
<pre>
object_list = Users.all().fetch(1000)
filtered = filter_helper(object_list, 'display_name', 'Rich')
</pre>
<p>This would filter a list of users to only users with the word &#8220;rich&#8221; in it&#8217;s display name.</p>
<p>You can download the full source <a href="/wp-content/uploads/2011/01/grid2.py">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://richwklein.com/2011/01/13/python-list-filter-helper/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Python In-Memory Sort Helper</title>
		<link>http://richwklein.com/2011/01/06/python-in-memory-sort-helper/</link>
		<comments>http://richwklein.com/2011/01/06/python-in-memory-sort-helper/#comments</comments>
		<pubDate>Thu, 06 Jan 2011 22:08:31 +0000</pubDate>
		<dc:creator>Rich</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[GAE]]></category>
		<category><![CDATA[Google]]></category>
		<category><![CDATA[Google App Engine]]></category>
		<category><![CDATA[Helper]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Sort]]></category>
		<category><![CDATA[Tip]]></category>
		<category><![CDATA[Trick]]></category>

		<guid isPermaLink="false">http://richwklein.com/?p=1796</guid>
		<description><![CDATA[I&#8217;ve been doing a lot of work on datagrids lately. My datagrid work is originally based off of Djblets datagrids. One of the cool things about these datagrids is the ability to sort by any column in the grid. This is a problem if the sorting occurs at the query level and you are dealing [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve been doing a lot of work on datagrids lately.  My datagrid work is originally based off of <a href="http://www.chipx86.com/blog/2008/07/25/django-development-with-djblets-data-grids/">Djblets datagrids</a>.  One of the cool things about these datagrids is the ability to sort by any column in the grid.  This is a problem if the sorting occurs at the query level and you are dealing with <a href="http://code.google.com/appengine/">Google App Engine</a> data models.  You could mitigate this by putting an index on every property on the model, but that isn&#8217;t a realistic solution.  I&#8217;ve come up with a different solution.  I pass an array of objects into the datagrid instead of a query and I have a helper function that sorts the objects in memory.  This helper has some cool features.</p>
<ul>
<li>It allows you to sort by returned values of object methods.</li>
<li>It allows you to sort the objects in ascending or descending value order.</li>
<li>It allows sorting by multiple attributes.</li>
<li>It does some basic value clean up before sorting for sort consistency.</li>
</ul>
<p><span id="more-1796"></span><br />
The code is commented fairly extensively so you should be able to figure out what I&#8217;m doing.</p>
<pre>
def sort_helper(object_list, sort_list, db_field_map=None):
    """
    Helper method for sorting object_lists.

    @param  object_list     An array of objects to sort.
    @param  sort_list       An array of names to sort by.
    @param  db_field_map    An optional dictionary that maps a sort name to an object's property or method.
    @return The sorted list
    """

    def clean(x):
        """
        Function that cleans the value to sort by.

        @param  x    The attribute on the object.
        @return The cleaned up value for sorting.
        """

        # attribute is a method so get the returned value
        v = x() if callable(x) else x

        # attribute is a string so convert it to lower case
        if type(v) == str or type(v) == unicode:
            v = v.lower()

        # attribute is a datetime so convert it to an epoch value
        elif type(v) == datetime.datetime:
            v = time.mktime(v.timetuple())

        # return the value
        return v

    # reverse the sort order so we get the correct sub-sorting
    sort_order = reversed(sort_list)

    # Generate the actual list of attributes we'll be sorting by
    for sort_item in sort_order:

        # -name so sort this attribute descending
        if sort_item[0] == '-':
            base_sort_item = sort_item[1:]
            reverse = True

        # Otherwise sort in ascending order
        else:
            base_sort_item = sort_item
            reverse = False

        # Check if the name is in the db field map
        if db_field_map:
            if not base_sort_item in db_field_map:
                continue
            db_field = db_field_map[base_sort_item]
        else:
            db_field = base_sort_item

        # Do the actual sort now
        try:
            object_list = sorted(object_list, key=lambda x: clean(getattr(x, db_field)), reverse=reverse)
        except Exception, e:
            logging.exception('sort_helper - %s' % unicode(e))

    return object_list
</pre>
<p>To use the helper you would do something like:</p>
<pre>
object_list = Users.all().fetch(1000)
sorted = sort_helper(object_list, ['-created', 'display_name'])
</pre>
<p>This would sort a list of users in decending created order then ascending display name.</p>
<p>You can download the full source <a href="/wp-content/uploads/2011/01/grid.py">here</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://richwklein.com/2011/01/06/python-in-memory-sort-helper/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Broadband Update</title>
		<link>http://richwklein.com/2010/11/10/broadband-update/</link>
		<comments>http://richwklein.com/2010/11/10/broadband-update/#comments</comments>
		<pubDate>Wed, 10 Nov 2010 16:07:24 +0000</pubDate>
		<dc:creator>Rich</dc:creator>
				<category><![CDATA[Family]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[Broadband]]></category>
		<category><![CDATA[Home]]></category>
		<category><![CDATA[Iowa]]></category>
		<category><![CDATA[Local]]></category>
		<category><![CDATA[New House]]></category>
		<category><![CDATA[Rant]]></category>

		<guid isPermaLink="false">http://richwklein.com/?p=1774</guid>
		<description><![CDATA[I ranted about my broadband frustrations in the previous post. An update to the story. Apparently the question to ask is not if I can get service to the home, but how much would it cost to get service to the home. After I talked with Mediacom a couple of more time I found out [...]]]></description>
			<content:encoded><![CDATA[<p>I ranted about my <a href="http://richwklein.com/2010/11/04/broadband-frustration/">broadband frustrations in the previous post</a>.  An update to the story.  Apparently the question to ask is not if I can get service to the home, but how much would it cost to get service to the home.  After I talked with <a href="http://mediacomcable.com/index.php">Mediacom</a> a couple of more time I found out that service can be brought to the home for $5,700.  Given that cable is really about the only broadband option I can work with, that is what we are going to do.</p>
]]></content:encoded>
			<wfw:commentRss>http://richwklein.com/2010/11/10/broadband-update/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Broadband Frustration</title>
		<link>http://richwklein.com/2010/11/04/broadband-frustration/</link>
		<comments>http://richwklein.com/2010/11/04/broadband-frustration/#comments</comments>
		<pubDate>Fri, 05 Nov 2010 03:57:49 +0000</pubDate>
		<dc:creator>Rich</dc:creator>
				<category><![CDATA[Family]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[Broadband]]></category>
		<category><![CDATA[Home]]></category>
		<category><![CDATA[Iowa]]></category>
		<category><![CDATA[Local]]></category>
		<category><![CDATA[New House]]></category>
		<category><![CDATA[Rant]]></category>

		<guid isPermaLink="false">http://richwklein.com/?p=1767</guid>
		<description><![CDATA[I&#8217;m a software engineer and one of the few fortunate individuals who gets to work out of their home. We purchased some land a couple of years ago with the intention of building a new home. We are now in the process of building that house. Being a remote employee doing software development, I need [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;m a software engineer and one of the few fortunate individuals who gets to work out of their home.  We purchased some land a couple of years ago with the intention of building a new home.  We are now in the process of building that house.  Being a remote employee doing software development, I need a pretty robust internet connection.  At the same time I knew that broadband availability would be a difficult thing to work out since the new house is in what I would call a semi-remote location.  I&#8217;ve previous <a href="http://richwklein.com/2009/08/17/state-of-broadband-in-rural-iowa/">complained</a> about broadband availability.  I&#8217;ve been a cable internet user for at least 12 years and I would like to continue to be.  It&#8217;s either that or pay the same price for 1/10th the speed and possible maximum usage caps.  </p>
<p>I contacted <a href="http://mediacomcable.com/index.php">Mediacom</a> to find out if service was available for our new home.  They responded that our house was not serviceable.  The image below (<a href="http://www.connectiowa.org/">from connect iowa</a>) illustrates  why this is so frustrating.  The red square is the lot we are building on.  The red/pink overlay is where cable is available.  I bet there isn&#8217;t a thousand feet between the two.<a class="thickbox" rel="same-post-1767" title = "coverage map" href="http://richwklein.com/wp-content/uploads/2010/11/Screen-shot-2010-11-04-at-10.21.30-PM.png"><img src="http://richwklein.com/wp-content/uploads/2010/11/Screen-shot-2010-11-04-at-10.21.30-PM-1024x517.png" alt="" title="coverage map" width="1024" height="517" class="alignnone size-large wp-image-1768" /></a></p>
]]></content:encoded>
			<wfw:commentRss>http://richwklein.com/2010/11/04/broadband-frustration/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>IE is Being Mean to Me</title>
		<link>http://richwklein.com/2010/03/26/ie-is-being-mean-to-me/</link>
		<comments>http://richwklein.com/2010/03/26/ie-is-being-mean-to-me/#comments</comments>
		<pubDate>Fri, 26 Mar 2010 16:14:05 +0000</pubDate>
		<dc:creator>Rich</dc:creator>
				<category><![CDATA[Media]]></category>
		<category><![CDATA[Work]]></category>
		<category><![CDATA[Explorer]]></category>
		<category><![CDATA[IE]]></category>
		<category><![CDATA[Internet]]></category>
		<category><![CDATA[Internet Explorer]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Mean]]></category>
		<category><![CDATA[Rant]]></category>
		<category><![CDATA[Video]]></category>
		<category><![CDATA[Viral]]></category>

		<guid isPermaLink="false">http://richwklein.com/?p=1509</guid>
		<description><![CDATA[I so feel this guys pain. I&#8217;ve been in the situation many times before trying to get javascript/html working cross browser.]]></description>
			<content:encoded><![CDATA[<p>I so feel this guys pain.  I&#8217;ve been in the situation many times before trying to get javascript/html working cross browser.<br />
<object class="video pad"><param name="movie" value="http://www.youtube.com/v/vTTzwJsHpU8&#038;hl=en_US&#038;fs=1&#038;"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/vTTzwJsHpU8&#038;hl=en_US&#038;fs=1&#038;" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://richwklein.com/2010/03/26/ie-is-being-mean-to-me/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>JavaScript Singletons in Firefox Add-ons</title>
		<link>http://richwklein.com/2010/01/19/javascript-singletons-in-firefox-add-ons/</link>
		<comments>http://richwklein.com/2010/01/19/javascript-singletons-in-firefox-add-ons/#comments</comments>
		<pubDate>Tue, 19 Jan 2010 21:20:08 +0000</pubDate>
		<dc:creator>Rich</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[Add-On]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Extension]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Hack]]></category>
		<category><![CDATA[Iframe]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[Service]]></category>
		<category><![CDATA[Singleton]]></category>
		<category><![CDATA[Tip]]></category>
		<category><![CDATA[Trick]]></category>
		<category><![CDATA[XPCOM]]></category>

		<guid isPermaLink="false">http://richwklein.com/?p=984</guid>
		<description><![CDATA[Occasionally when developing add-ons for Firefox, you want your JavaScript to only run once for the lifetime of the application. Normally, you would place your code in a browser overlay, but this causes the code to run every time a new window is opened. There are several ways to get around this. You could write [...]]]></description>
			<content:encoded><![CDATA[<p>Occasionally when developing <a href="http://addons.mozilla.org">add-ons</a> for <a href="http://getfirefox.com">Firefox</a>, you want your JavaScript to only run once for the lifetime of the application.  Normally, you would place your code in a browser overlay, but this causes the code to run every time a new window is opened.  There are several ways to get around this.  You could write an <a href="https://developer.mozilla.org/en/XPCOM">XPCOM service</a> or use a <a href="https://developer.mozilla.org/en/JavaScript_code_modules">JavaScript module</a>.  These are both valid methods and work very well if your code is Firefox specific.  However, if you are also writing your add-on for <a href="http://www.google.com/chrome">Chrome</a>, you might want the code to be able to run in both places.  Here is a nice little hack that uses the hidden window so that you can run your <a href="http://code.google.com/chrome/extensions/background_pages.html">Chrome background page</a> within an iframe in Firefox. </p>
<p><span id="more-984"></span></p>
<pre>

  function getBackgroundPage(id, src) {

    // get the firefox hidden window
    var win = Components.classes["@mozilla.org/appshell/appShellService;1"].
                   getService(Components.interfaces.nsIAppShellService).
                   hiddenDOMWindow;

    // if the iframe was previously loaded store it and callback
    var iframe = win.document.getElementsById(id);
    if (iframe)
      return iframe.contentWindow;

    // create the iframe
    iframe = win.document.createElement("iframe");
    iframe.setAttribute("id", id);
    iframe.setAttribute("style", "display:none;");

    // load the source
    iframe.setAttribute("src", src);
    win.document.documentElement.appendChild(iframe);

    // return the content window
    return iframe.contentWindow;
</pre>
<p>Now you can access your background page by including the script in your overlay and doing:</p>
<pre>
  var bgp = getBackgroundPage("id for background page", "url of the background page");
</pre>
<p>** UPDATE **<br />
instead of setting the style to display:none you should instead set the attribute &#8220;collapsed&#8221; to true.  This causes docshell errors in some cases.</p>
<p><strike>iframe.setAttribute(&#8220;style&#8221;, &#8220;display:none;&#8221;);</strike><br />
iframe.setAttribute(&#8220;collapsed&#8221;, &#8220;true&#8221;);</p>
]]></content:encoded>
			<wfw:commentRss>http://richwklein.com/2010/01/19/javascript-singletons-in-firefox-add-ons/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Web Tech Studios</title>
		<link>http://richwklein.com/2009/12/23/web-tech-studios/</link>
		<comments>http://richwklein.com/2009/12/23/web-tech-studios/#comments</comments>
		<pubDate>Wed, 23 Dec 2009 20:55:57 +0000</pubDate>
		<dc:creator>Rich</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[Contract]]></category>
		<category><![CDATA[Studios]]></category>
		<category><![CDATA[Tech]]></category>
		<category><![CDATA[Web]]></category>
		<category><![CDATA[Web Tech Studios]]></category>
		<category><![CDATA[WTS]]></category>

		<guid isPermaLink="false">http://richwklein.com/?p=969</guid>
		<description><![CDATA[Web Tech Studios is a company I created to cover the work I do in my spare time. The focus of the company is providing custom solutions for clients. We will also supply free Firefox add-ons. For the add-ons we are asking for donations to cover the development cost. After much trial and error the [...]]]></description>
			<content:encoded><![CDATA[<p>Web Tech Studios is a company I created to cover the work I do in my spare time.  The focus of the company is providing custom solutions for clients.  We will also supply free Firefox add-ons.  For the add-ons we are asking for donations to cover the development cost.</p>
<p>After much trial and error the <a href="http://webtechstudios.com">website</a> for my company &#8220;Web Tech Studios&#8221; is now live.  Please, look it over and let me know what you think.  You can also follow me on twitter <a href="http://twitter.com/webtechstudios">@webtechstudios</a>.</p>
]]></content:encoded>
			<wfw:commentRss>http://richwklein.com/2009/12/23/web-tech-studios/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Diamond in the HTML &#8220;Rough&#8221;</title>
		<link>http://richwklein.com/2009/12/08/diamond-in-the-html-rough/</link>
		<comments>http://richwklein.com/2009/12/08/diamond-in-the-html-rough/#comments</comments>
		<pubDate>Tue, 08 Dec 2009 17:12:35 +0000</pubDate>
		<dc:creator>Rich</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[Add-On]]></category>
		<category><![CDATA[Clover]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[CSS]]></category>
		<category><![CDATA[Diamond]]></category>
		<category><![CDATA[Extension]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[Hack]]></category>
		<category><![CDATA[HTML]]></category>
		<category><![CDATA[Javascript]]></category>
		<category><![CDATA[KwiClick]]></category>
		<category><![CDATA[Search]]></category>
		<category><![CDATA[Search Clover]]></category>
		<category><![CDATA[Shadow]]></category>
		<category><![CDATA[Transform]]></category>

		<guid isPermaLink="false">http://richwklein.com/?p=937</guid>
		<description><![CDATA[For the latest version of KwiClick we introduced a feature called search clovers. When you highlight a word on a page, a single diamond shaped &#8220;clover&#8221; appears. When you hover over the diamond, 3 more diamonds appear creating a 4 leaf clover configuration. To create these diamonds we use two html tags, an img surrounded [...]]]></description>
			<content:encoded><![CDATA[<p><a href="http://richwklein.com/wp-content/uploads/2009/12/clovers.png"><img src="http://richwklein.com/wp-content/uploads/2009/12/clovers.png" alt="KwiClick Search Clovers" title="KwiClick Search Clovers" width="106" height="125" class="alignleft pad" /></a>For the latest <a href="https://addons.mozilla.org/en-US/firefox/addon/5655">version</a> of <a href="http://www.kwiclick.com/">KwiClick</a> we introduced a feature called search clovers.  When you highlight a word on a page, a single diamond shaped &#8220;clover&#8221; appears.  When you hover over the diamond, 3 more diamonds appear creating a 4 leaf clover configuration.  To create these diamonds we use two html tags, an img surrounded by a div.  <a href="http://richwklein.com/wp-content/uploads/2009/12/cloveroverlap.png"><img src="http://richwklein.com/wp-content/uploads/2009/12/cloveroverlap.png" alt="Clover Overlap" title="Clover Overlap" width="91" height="89" class="alignright pad" /></a>In Firefox versions prior to 3.5 we used a background image on the div to create the look of a the diamond.  The corners of the images overlapped each other causing problems when a user tried to hover or click on one of them.</p>
<p><span id="more-937"></span><br />
With Firefox 3.5 we were able to fix this by creating the diamond using only html and some specialized css tags.  Using the tags: -moz-transform, -moz-border-radius, and -moz-box-shadow we rotate the div 45 degrees and add a shadow to them.</p>
<pre>
  display: inline-block !important;
  border: 2px solid #494949 !important;
  background: none !important;
  background-color: white !important;
  -moz-transform: rotate(45deg) !important;
  -moz-border-radius: 4px !important;
  -moz-box-shadow: grey 2px 2px 2px !important;
</pre>
<p> This also rotates the content within the div.  To fix that we rotate the image back 45 degrees. </p>
<pre>
  -moz-transform: rotate(-45deg) !important;
</pre>
<p>And viola, a diamond with all the html event goodness, made with only html and css.  Safari and Chrome support these transforms with -webkit-transform so this same effect can be used there.  </p>
]]></content:encoded>
			<wfw:commentRss>http://richwklein.com/2009/12/08/diamond-in-the-html-rough/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Caching Parsed Django Templates</title>
		<link>http://richwklein.com/2009/12/01/caching-parsed-django-templates/</link>
		<comments>http://richwklein.com/2009/12/01/caching-parsed-django-templates/#comments</comments>
		<pubDate>Tue, 01 Dec 2009 17:09:18 +0000</pubDate>
		<dc:creator>Rich</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[Cache]]></category>
		<category><![CDATA[Code]]></category>
		<category><![CDATA[Compile]]></category>
		<category><![CDATA[Django]]></category>
		<category><![CDATA[Python]]></category>
		<category><![CDATA[Template]]></category>
		<category><![CDATA[Tip]]></category>
		<category><![CDATA[Trick]]></category>

		<guid isPermaLink="false">http://richwklein.com/?p=924</guid>
		<description><![CDATA[Standard Django rendering parses a template every time it is rendered. Storing the parsed template can be a nice little speed up for your Django site. This code snippet does a great job of doing that for all templates. One drawback to this approach though is that the server needs restarted whenever a template changes. [...]]]></description>
			<content:encoded><![CDATA[<p>Standard <a href="http://www.djangoproject.com/">Django</a> rendering parses a template every time it is rendered.  Storing the parsed template can be a nice little speed up for your Django site.  <a href="http://www.djangosnippets.org/snippets/507/">This</a> code snippet does a great job of doing that for all templates.  One drawback to this approach though is that the server needs restarted whenever a template changes.  I&#8217;ve taken a slightly different approach to this where I create a separate method for caching and rendering templates.  I only call this when rendering several templates in a view and the speed up is absolutely necessary.  Some places you might consider doing this is when sending out bulk emails or when rendering a long list of objects and each object uses the same template.</p>
<p>First create a file called template.py in your application.  Then we create a method that will cache a template when called and return the rendered template.</p>
<pre>
from django.template import Context, loader

template_cache = {}
def render_cached(template_name, dictionary=None):
    global template_cache

    t = template_cache.get(template_name, None)
    if not t or settings.DEBUG:
        template_cache[template_name] = t = loader.get_template(template_name)

    dictionary = dictionary or {}
    context_instance = Context(dictionary)
    return t.render(context_instance)
</pre>
<p>This method takes two arguments the template name and a dictionary to use for the template context.  It first gets the template out of the cache.  It then looks if the template was retrieved or if your debug setting is on.  If either of these cases exist, it uses the base django loader to retrieve the parsed template and store it in the cache dictionary.  Then we create a context instance for the dictionary and return the rendered code.</p>
<p>To be able to use the method you just import and call it.</p>
<pre>
from template import render_cached
html = render_cached("sometemplate.html", {})
</pre>
]]></content:encoded>
			<wfw:commentRss>http://richwklein.com/2009/12/01/caching-parsed-django-templates/feed/</wfw:commentRss>
		<slash:comments>6</slash:comments>
		</item>
		<item>
		<title>KwiClick 2.4.1</title>
		<link>http://richwklein.com/2009/11/29/kwiclick-2-4-1/</link>
		<comments>http://richwklein.com/2009/11/29/kwiclick-2-4-1/#comments</comments>
		<pubDate>Sun, 29 Nov 2009 13:58:28 +0000</pubDate>
		<dc:creator>Rich</dc:creator>
				<category><![CDATA[Work]]></category>
		<category><![CDATA[Add-On]]></category>
		<category><![CDATA[Clover]]></category>
		<category><![CDATA[Extension]]></category>
		<category><![CDATA[Firefox]]></category>
		<category><![CDATA[KwiClick]]></category>
		<category><![CDATA[Search]]></category>
		<category><![CDATA[Search Clover]]></category>
		<category><![CDATA[Update]]></category>
		<category><![CDATA[Version]]></category>

		<guid isPermaLink="false">http://richwklein.com/?p=917</guid>
		<description><![CDATA[KwiClick 2.4.1 was released on AMO this week. This is a pretty large update from the last AMO release so make sure to check it out. Here is a list of what is new in this release: New Search Clovers for selection based searching functionality Updated Bing provider Updated compatibility for ff 3.6betas Improve sqlite [...]]]></description>
			<content:encoded><![CDATA[<p><a href="https://addons.mozilla.org/en-US/firefox/addon/5655">KwiClick 2.4.1</a> was released on AMO this week.  This is a pretty large update from the last AMO release so make sure to check it out.  Here is a list of what is new in this release:</p>
<ul>
<li>New Search Clovers for selection based searching functionality</li>
<li>Updated Bing provider</li>
<li>Updated compatibility for ff 3.6betas</li>
<li>Improve sqlite performance</li>
<li>Trim leading and trailing spaces from searches to improve accuracy</li>
<li>Updated kwiclick skin</li>
<li>Replace getBoxObjectFor with getBoundingClientRect</li>
<li>Clover preferences to fine tune functionality</li>
<li>Turn on/off clover from statusbar button</li>
<li>Updated wikipedia provider increases accuracy of searching and results</li>
</ul>
<p>Here is the video for the 2.4 release which was submitted to the extend firefox contest.  This is a pretty good explanation of the things you can do with <a href="http://kwiclick.com">KwiClick</a>.<br />
<object class="pad video"><param name="movie" value="http://www.youtube.com/v/tsP7LuuRWPQ&#038;hl=en_US&#038;fs=1"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/tsP7LuuRWPQ&#038;hl=en_US&#038;fs=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true"></embed></object></p>
]]></content:encoded>
			<wfw:commentRss>http://richwklein.com/2009/11/29/kwiclick-2-4-1/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

<!-- Dynamic Page Served (once) in 0.305 seconds -->

