{"id":59,"date":"2010-07-10T14:11:00","date_gmt":"2010-07-10T21:11:00","guid":{"rendered":"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/harvest-stuff-for-gsoc-week-7\/"},"modified":"2024-08-14T09:20:05","modified_gmt":"2024-08-14T16:20:05","slug":"harvest-stuff-for-gsoc-week-7","status":"publish","type":"post","link":"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/","title":{"rendered":"Harvest stuff for GSoC: Week 7!"},"content":{"rendered":"\n<p>Time for my bi-weekly Harvest update! Everything this time went into the <a href=\"https:\/\/code.edge.launchpad.net\/~dylanmccall\/harvest\/gsoc-client-stuff\">gsoc-client-stuff branch<\/a>.<\/p>\n\n\n\n<p>The first thing I learned (well, <em>decided<\/em>) is that YUI has incredibly dense, loopy and uncool documentation. I guess different people are compatible with different kinds of docs. As I read the YUI stuff I just couldn&#8217;t keep it all straight for some reason. Its landing page leads off in many directions: there&#8217;s an API reference that was written and designed to put me to sleep, an Examples section that doesn&#8217;t bother to link to the API reference (but <em>is<\/em> more pleasantly written), and a lot of extra listings in between.<\/p>\n\n\n\n<!--more-->\n\n\n\n<p>All I could think about was how much I preferred JQuery\u2019s docs. So, I dropped YUI for JQuery and nothing has exploded. In fact, it&#8217;s all gone wonderfully.<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/week7-namefield\/\" rel=\"attachment wp-att-516\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"300\" height=\"273\" data-attachment-id=\"516\" data-permalink=\"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/week7-namefield\/\" data-orig-file=\"https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-namefield.png?fit=517%2C472&amp;ssl=1\" data-orig-size=\"517,472\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}\" data-image-title=\"week7-namefield\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-namefield.png?fit=300%2C273&amp;ssl=1\" data-large-file=\"https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-namefield.png?fit=517%2C472&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-namefield.png?resize=300%2C273&#038;ssl=1\" alt=\"\" class=\"wp-image-516\" title=\"week7-namefield\" srcset=\"https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-namefield.png?resize=300%2C273&amp;ssl=1 300w, https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-namefield.png?w=517&amp;ssl=1 517w\" sizes=\"auto, (max-width: 300px) 100vw, 300px\" \/><\/a><\/figure><\/div>\n\n\n\n<p>JQuery has a considerably simpler core than YUI, but there is lots of functionality in little self-contained plugins. Some of these are official parts of the project, others are external things linked from the plugin repository. (Granted, lots of redundancy there). It&#8217;s a different approach \u2014 YUI is richer from the start \u2014 but for me, JQuery wins by being so much easier to take in at a glance. That, and its documentation is a lot prettier. Instead of your boring automatically generated list of docstrings attached to function names, they have a beautifully presented web app. There are no frustrating stubs; everything I may think to use is there and explained in detail. And it&#8217;s a single destination. One page to learn everything there is to know about each bit of functionality in JQuery, including examples. Pretty cool.<br>JQuery, I promise I will always love you :)<\/p>\n\n\n\n<p>I also learned about doing object-oriented Javascript. This one surprised me. I have used Javascript for lots of small jobs before, but I have never used it with anything big. I realized Javascript doesn&#8217;t have the&nbsp;<em>class<\/em> keyword I have come to love, but after some learning I am back to thinking it&#8217;s a pretty cool scripting language. That is mainly thanks to <a href=\"http:\/\/www.phpied.com\/3-ways-to-define-a-javascript-class\/\">an excellent blog post by Stoyan Stefanov<\/a>, all about doing classes in Javascript. Everything is an object, so of course we don&#8217;t <em>need<\/em> a class keyword! (Apparently we&#8217;re getting one some time this century, though, if everyone is nice to it).<\/p>\n\n\n\n<p>Making something that feels like a class is a bit of a hack, but it works elegantly in the end. It\u2019s really just a function, and we put other functions and things inside it for methods and properties. I\u2019m doing them like this:<code>function Filter (dom_node) { var filter = this; this.get_value_serialized = function () { return null; }}<\/code><\/p>\n\n\n\n<p>To create an instance we use Javascript&#8217;s <em>new<\/em> keyword and write out the function as usual (including its parameters). The <em>this<\/em> keyword can&#8217;t be trusted if we are using callback functions, because each function is given its own version based on what object it is being called with. (If it&#8217;s via a reference to a function stored somewhere else, things get messy). On the other hand, anything inside Filter can see that <em>filter<\/em> variable we created at the top, as well as the <em>dom_node<\/em> parameter.<\/p>\n\n\n\n<p>Those variables pointing at functions, of course, can be really easily reassigned to point at different functions. Lots of power here.&nbsp;For fancier stuff, including multiple inheritance (yes, it gets crazier), Mike Koss has <a href=\"http:\/\/mckoss.com\/jscript\/object.htm\">an excellent article<\/a>. In my case, I decided not to go into that. (Well, okay, I chickened out then called it a decision). Proper subclasses might make my code look smarter, but in this case&nbsp;that whole chunk barely needs to do anything anyway, so I&#8217;m fine how it is.<\/p>\n\n\n\n<p>With that all out of the way, I worked on a really fun list of new stuff!<\/p>\n\n\n\n<p>I have Harvest using XHR in a few different places now. XHR is a wonderful thing that lets us directly request new data for our page and handle it through Javascript. It means, if you want to select a bunch of filters, you can do it without flooding our server with each one.<\/p>\n\n\n\n<p>When a filter&#8217;s value is changed, it posts the query parameter that change represents to the global Results object. (Some goodies here: if you change the value of a filter in a positive way, that filter is selected implicitly). Instead of instantly yapping at the server, the Results object stores the parameter it receives in an object (dictionary style) and starts (or restarts) its timer. When the timer finishes, it uses JQuery&#8217;s $.get function to request new results for the selected filters, passing the function its dictionary of new parameters. (JQuery magically turns that into a querystring for us, so if something weird happens and everyone decides to use something else, Harvest will still work).<\/p>\n\n\n\n<p>The result surprised me. I&#8217;m still not doing much to limit the number of results, but even with a query that returns the most packages possible (around 3700 at once) the whole thing feels a lot quicker than it did. Funny\u2026<\/p>\n\n\n\n<p>The next one is expanding packages. When the user clicks a package, we send another http request asking for that package&#8217;s details. We get a snippet of HTML back from the server, throw it in the right element and reveal it with an animation. (Did I mention I love JQuery?).<\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/week7-loadingpackage\/\" rel=\"attachment wp-att-517\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"525\" height=\"225\" data-attachment-id=\"517\" data-permalink=\"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/week7-loadingpackage\/\" data-orig-file=\"https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-loadingpackage.png?fit=999%2C430&amp;ssl=1\" data-orig-size=\"999,430\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}\" data-image-title=\"week7-loadingpackage\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-loadingpackage.png?fit=300%2C129&amp;ssl=1\" data-large-file=\"https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-loadingpackage.png?fit=525%2C225&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-loadingpackage.png?resize=525%2C225&#038;ssl=1\" alt=\"\" class=\"wp-image-517\" title=\"week7-loadingpackage\" srcset=\"https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-loadingpackage.png?resize=750%2C322&amp;ssl=1 750w, https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-loadingpackage.png?resize=300%2C129&amp;ssl=1 300w, https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-loadingpackage.png?w=999&amp;ssl=1 999w\" sizes=\"auto, (max-width: 706px) 89vw, (max-width: 767px) 82vw, 740px\" \/><\/a><\/figure><\/div>\n\n\n\n<div class=\"separator\" style=\"clear: both; text-align: center;\"><small>By the way, I worked on the visual design for packages. Any comments? Thoughts on the arbitrary green highlight?<\/small><\/div>\n\n\n\n<p>I don&#8217;t trust http requests going on unchecked. So, as is the convention, I added little \u201cloading\u201d indicators (from the very helpful and sickeningly popular <a href=\"http:\/\/ajaxload.info\/\">ajaxload.info<\/a>). It was really distracting to have these appear all the time, though, so I played with it and now the indicators will slowly fade in. A loading indicator should only become obvious if there is a long operation going on. If everything is normal and the operation is nearly instant, the indicator stays out of the way.<\/p>\n\n\n\n<p>I went two whole days without an Internet connection this week (oh, the humanity!), so I was thinking about people with similar predicaments. It sucks when an application decides it wants to download something and keeps on trying and trying, oblivious to my repeated attempts to convince it&nbsp;<em>I have no connection<\/em>. JQuery&#8217;s $.get function returns an object to control the http request, so I store that using the $.data method:<code>package_node.data('xhr', xhr);<\/code>Later, if someone tries to collapse a package that was still loading its details before expanding, we can do something like:<code>package_node.data('xhr').abort();<\/code>We give $.get a callback function that is run when the request is finished \u2014 be it successful, an error from the server, or an abort. So, cleanup (like removing the loading indicator) can all be done there.<\/p>\n\n\n\n<p>The Django debug-toolbar only kicks in when we load a whole new page inheriting from the base template, so I had to try something new to gauge performance. In this case I found a <a href=\"http:\/\/djangosnippets.org\/snippets\/797\/\">cool bit of middleware<\/a> at DjangoSnippets.org. It adds a header for every page Django creates, saying how long it took to generate. It isn&#8217;t much information, but it helps! What I like here is it doesn&#8217;t edit the page at all and it&#8217;s a really small bit of code; it is as unobtrusive as possible. The data is always visible with a tool like Firebug or Webkit&#8217;s web inspector (or telnet, if you&#8217;re crazy). It is super easy to present this with Javascript, too:<code>time_header = xhr.getResponseHeader('X-Django-Request-Time')if (time_header) { $('#requeststats').html('Results generated in '+parseFloat(time_header).toFixed(2) + ' seconds');}<\/code><\/p>\n\n\n\n<div class=\"wp-block-image\"><figure class=\"aligncenter\"><a href=\"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/week7-footer\/\" rel=\"attachment wp-att-518\"><img data-recalc-dims=\"1\" loading=\"lazy\" decoding=\"async\" width=\"525\" height=\"75\" data-attachment-id=\"518\" data-permalink=\"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/week7-footer\/\" data-orig-file=\"https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-footer.png?fit=1003%2C144&amp;ssl=1\" data-orig-size=\"1003,144\" data-comments-opened=\"0\" data-image-meta=\"{&quot;aperture&quot;:&quot;0&quot;,&quot;credit&quot;:&quot;&quot;,&quot;camera&quot;:&quot;&quot;,&quot;caption&quot;:&quot;&quot;,&quot;created_timestamp&quot;:&quot;0&quot;,&quot;copyright&quot;:&quot;&quot;,&quot;focal_length&quot;:&quot;0&quot;,&quot;iso&quot;:&quot;0&quot;,&quot;shutter_speed&quot;:&quot;0&quot;,&quot;title&quot;:&quot;&quot;}\" data-image-title=\"week7-footer\" data-image-description=\"\" data-image-caption=\"\" data-medium-file=\"https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-footer.png?fit=300%2C43&amp;ssl=1\" data-large-file=\"https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-footer.png?fit=525%2C75&amp;ssl=1\" src=\"https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-footer.png?resize=525%2C75&#038;ssl=1\" alt=\"\" class=\"wp-image-518\" title=\"week7-footer\" srcset=\"https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-footer.png?resize=750%2C107&amp;ssl=1 750w, https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-footer.png?resize=300%2C43&amp;ssl=1 300w, https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-footer.png?w=1003&amp;ssl=1 1003w\" sizes=\"auto, (max-width: 706px) 89vw, (max-width: 767px) 82vw, 740px\" \/><\/a><\/figure><\/div>\n\n\n\n<p>And that is that! There is lots of polish left to do for next week, and a strange headache of a merge conflict to resolve. Assuming bzr doesn\u2019t eat anyone\u2019s work, things are really picking up!<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Time for my bi-weekly Harvest update! Everything this time went into the <a href=\"https:\/\/code.edge.launchpad.net\/~dylanmccall\/harvest\/gsoc-client-stuff\">gsoc-client-stuff branch<\/a>.<\/p>\n<p>The first thing I learned (well, <em>decided<\/em>) is that YUI has incredibly dense, loopy and uncool documentation. I guess different people are compatible with different kinds of docs. As I read the YUI stuff I just couldn&#8217;t keep it all straight for some reason. Its landing page leads off in many directions: there&#8217;s an API reference that was written and designed to put me to sleep, an Examples section that doesn&#8217;t bother to link to the API reference (but <em>is<\/em> more pleasantly written), and a lot of extra listings in between&hellip;<\/p>\n","protected":false},"author":2,"featured_media":516,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"jetpack_post_was_ever_published":false,"_jetpack_newsletter_access":"","_jetpack_dont_email_post_to_subs":false,"_jetpack_newsletter_tier_id":0,"_jetpack_memberships_contains_paywalled_content":false,"_jetpack_memberships_contains_paid_content":false,"activitypub_content_warning":"","activitypub_content_visibility":"","activitypub_max_image_attachments":3,"activitypub_interaction_policy_quote":"anyone","activitypub_status":"federate","footnotes":"","jetpack_publicize_message":"","jetpack_publicize_feature_enabled":true,"jetpack_social_post_already_shared":false,"jetpack_social_options":{"image_generator_settings":{"template":"highway","default_image_id":0,"font":"","enabled":false},"version":2}},"categories":[35],"tags":[36,20,37,24,29],"class_list":["post-59","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-gsoc-2010","tag-django","tag-harvest","tag-javascript","tag-jquery","tag-web"],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.1.1 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Harvest stuff for GSoC: Week 7! - Dylan McCall<\/title>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/\" \/>\n<meta property=\"og:locale\" content=\"en_US\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Harvest stuff for GSoC: Week 7! - Dylan McCall\" \/>\n<meta property=\"og:description\" content=\"Time for my bi-weekly Harvest update! Everything this time went into the gsoc-client-stuff branch.  The first thing I learned (well, decided) is that YUI has incredibly dense, loopy and uncool documentation. I guess different people are compatible with different kinds of docs. As I read the YUI stuff I just couldn&#8217;t keep it all straight for some reason. Its landing page leads off in many directions: there&#8217;s an API reference that was written and designed to put me to sleep, an Examples section that doesn&#8217;t bother to link to the API reference (but is more pleasantly written), and a lot of extra listings in between&hellip;\" \/>\n<meta property=\"og:url\" content=\"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/\" \/>\n<meta property=\"og:site_name\" content=\"Dylan McCall\" \/>\n<meta property=\"article:published_time\" content=\"2010-07-10T21:11:00+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2024-08-14T16:20:05+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/dylanmc.ca\/wp-content\/uploads\/week7-namefield.png\" \/>\n\t<meta property=\"og:image:width\" content=\"517\" \/>\n\t<meta property=\"og:image:height\" content=\"472\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/png\" \/>\n<meta name=\"author\" content=\"Dylan McCall\" \/>\n<meta name=\"twitter:label1\" content=\"Written by\" \/>\n\t<meta name=\"twitter:data1\" content=\"Dylan McCall\" \/>\n\t<meta name=\"twitter:label2\" content=\"Est. reading time\" \/>\n\t<meta name=\"twitter:data2\" content=\"7 minutes\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\/\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/#article\",\"isPartOf\":{\"@id\":\"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/\"},\"author\":{\"name\":\"Dylan McCall\",\"@id\":\"https:\/\/dylanmc.ca\/\/-\/#\/schema\/person\/c244419a779c5414c768bc53ac5fb2d5\"},\"headline\":\"Harvest stuff for GSoC: Week 7!\",\"datePublished\":\"2010-07-10T21:11:00+00:00\",\"dateModified\":\"2024-08-14T16:20:05+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/\"},\"wordCount\":1296,\"image\":{\"@id\":\"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-namefield.png?fit=517%2C472&ssl=1\",\"keywords\":[\"django\",\"Harvest\",\"javascript\",\"jquery\",\"web\"],\"articleSection\":[\"GSoC 2010\"],\"inLanguage\":\"en-US\"},{\"@type\":\"WebPage\",\"@id\":\"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/\",\"url\":\"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/\",\"name\":\"Harvest stuff for GSoC: Week 7! - Dylan McCall\",\"isPartOf\":{\"@id\":\"https:\/\/dylanmc.ca\/\/-\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/#primaryimage\"},\"image\":{\"@id\":\"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/#primaryimage\"},\"thumbnailUrl\":\"https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-namefield.png?fit=517%2C472&ssl=1\",\"datePublished\":\"2010-07-10T21:11:00+00:00\",\"dateModified\":\"2024-08-14T16:20:05+00:00\",\"author\":{\"@id\":\"https:\/\/dylanmc.ca\/\/-\/#\/schema\/person\/c244419a779c5414c768bc53ac5fb2d5\"},\"inLanguage\":\"en-US\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/#primaryimage\",\"url\":\"https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-namefield.png?fit=517%2C472&ssl=1\",\"contentUrl\":\"https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-namefield.png?fit=517%2C472&ssl=1\",\"width\":\"517\",\"height\":\"472\"},{\"@type\":\"WebSite\",\"@id\":\"https:\/\/dylanmc.ca\/\/-\/#website\",\"url\":\"https:\/\/dylanmc.ca\/\/-\/\",\"name\":\"Dylan McCall\",\"description\":\"\",\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\/\/dylanmc.ca\/\/-\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"en-US\"},{\"@type\":\"Person\",\"@id\":\"https:\/\/dylanmc.ca\/\/-\/#\/schema\/person\/c244419a779c5414c768bc53ac5fb2d5\",\"name\":\"Dylan McCall\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"en-US\",\"@id\":\"https:\/\/dylanmc.ca\/\/-\/#\/schema\/person\/image\/\",\"url\":\"https:\/\/secure.gravatar.com\/avatar\/c94ab3a7e6a884542205e0408711cd54bb1fd5f4e90e7a5f621a54656a18a037?s=96&d=mm&r=g\",\"contentUrl\":\"https:\/\/secure.gravatar.com\/avatar\/c94ab3a7e6a884542205e0408711cd54bb1fd5f4e90e7a5f621a54656a18a037?s=96&d=mm&r=g\",\"caption\":\"Dylan McCall\"},\"description\":\"Software developer, tea drinker, GNOME contributor. Occasionally a raving fanatic.\",\"sameAs\":[\"https:\/\/dylanmc.ca\/\/-\"],\"url\":\"https:\/\/dylanmc.ca\/\/-\/blog\/author\/dylan\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Harvest stuff for GSoC: Week 7! - Dylan McCall","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/","og_locale":"en_US","og_type":"article","og_title":"Harvest stuff for GSoC: Week 7! - Dylan McCall","og_description":"Time for my bi-weekly Harvest update! Everything this time went into the gsoc-client-stuff branch.  The first thing I learned (well, decided) is that YUI has incredibly dense, loopy and uncool documentation. I guess different people are compatible with different kinds of docs. As I read the YUI stuff I just couldn&#8217;t keep it all straight for some reason. Its landing page leads off in many directions: there&#8217;s an API reference that was written and designed to put me to sleep, an Examples section that doesn&#8217;t bother to link to the API reference (but is more pleasantly written), and a lot of extra listings in between&hellip;","og_url":"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/","og_site_name":"Dylan McCall","article_published_time":"2010-07-10T21:11:00+00:00","article_modified_time":"2024-08-14T16:20:05+00:00","og_image":[{"width":517,"height":472,"url":"https:\/\/dylanmc.ca\/wp-content\/uploads\/week7-namefield.png","type":"image\/png"}],"author":"Dylan McCall","twitter_misc":{"Written by":"Dylan McCall","Est. reading time":"7 minutes"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/#article","isPartOf":{"@id":"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/"},"author":{"name":"Dylan McCall","@id":"https:\/\/dylanmc.ca\/\/-\/#\/schema\/person\/c244419a779c5414c768bc53ac5fb2d5"},"headline":"Harvest stuff for GSoC: Week 7!","datePublished":"2010-07-10T21:11:00+00:00","dateModified":"2024-08-14T16:20:05+00:00","mainEntityOfPage":{"@id":"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/"},"wordCount":1296,"image":{"@id":"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-namefield.png?fit=517%2C472&ssl=1","keywords":["django","Harvest","javascript","jquery","web"],"articleSection":["GSoC 2010"],"inLanguage":"en-US"},{"@type":"WebPage","@id":"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/","url":"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/","name":"Harvest stuff for GSoC: Week 7! - Dylan McCall","isPartOf":{"@id":"https:\/\/dylanmc.ca\/\/-\/#website"},"primaryImageOfPage":{"@id":"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/#primaryimage"},"image":{"@id":"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/#primaryimage"},"thumbnailUrl":"https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-namefield.png?fit=517%2C472&ssl=1","datePublished":"2010-07-10T21:11:00+00:00","dateModified":"2024-08-14T16:20:05+00:00","author":{"@id":"https:\/\/dylanmc.ca\/\/-\/#\/schema\/person\/c244419a779c5414c768bc53ac5fb2d5"},"inLanguage":"en-US","potentialAction":[{"@type":"ReadAction","target":["https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/"]}]},{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/dylanmc.ca\/\/-\/blog\/2010\/07\/10\/harvest-stuff-for-gsoc-week-7\/#primaryimage","url":"https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-namefield.png?fit=517%2C472&ssl=1","contentUrl":"https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-namefield.png?fit=517%2C472&ssl=1","width":"517","height":"472"},{"@type":"WebSite","@id":"https:\/\/dylanmc.ca\/\/-\/#website","url":"https:\/\/dylanmc.ca\/\/-\/","name":"Dylan McCall","description":"","potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/dylanmc.ca\/\/-\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"en-US"},{"@type":"Person","@id":"https:\/\/dylanmc.ca\/\/-\/#\/schema\/person\/c244419a779c5414c768bc53ac5fb2d5","name":"Dylan McCall","image":{"@type":"ImageObject","inLanguage":"en-US","@id":"https:\/\/dylanmc.ca\/\/-\/#\/schema\/person\/image\/","url":"https:\/\/secure.gravatar.com\/avatar\/c94ab3a7e6a884542205e0408711cd54bb1fd5f4e90e7a5f621a54656a18a037?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/c94ab3a7e6a884542205e0408711cd54bb1fd5f4e90e7a5f621a54656a18a037?s=96&d=mm&r=g","caption":"Dylan McCall"},"description":"Software developer, tea drinker, GNOME contributor. Occasionally a raving fanatic.","sameAs":["https:\/\/dylanmc.ca\/\/-"],"url":"https:\/\/dylanmc.ca\/\/-\/blog\/author\/dylan\/"}]}},"jetpack_publicize_connections":[],"jetpack_featured_media_url":"https:\/\/i0.wp.com\/dylanmc.ca\/wp-content\/uploads\/week7-namefield.png?fit=517%2C472&ssl=1","jetpack_shortlink":"https:\/\/wp.me\/pcXOQX-X","jetpack_sharing_enabled":true,"_links":{"self":[{"href":"https:\/\/dylanmc.ca\/\/-\/wp-json\/wp\/v2\/posts\/59","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/dylanmc.ca\/\/-\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/dylanmc.ca\/\/-\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/dylanmc.ca\/\/-\/wp-json\/wp\/v2\/users\/2"}],"replies":[{"embeddable":true,"href":"https:\/\/dylanmc.ca\/\/-\/wp-json\/wp\/v2\/comments?post=59"}],"version-history":[{"count":11,"href":"https:\/\/dylanmc.ca\/\/-\/wp-json\/wp\/v2\/posts\/59\/revisions"}],"predecessor-version":[{"id":11026,"href":"https:\/\/dylanmc.ca\/\/-\/wp-json\/wp\/v2\/posts\/59\/revisions\/11026"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/dylanmc.ca\/\/-\/wp-json\/wp\/v2\/media\/516"}],"wp:attachment":[{"href":"https:\/\/dylanmc.ca\/\/-\/wp-json\/wp\/v2\/media?parent=59"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/dylanmc.ca\/\/-\/wp-json\/wp\/v2\/categories?post=59"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/dylanmc.ca\/\/-\/wp-json\/wp\/v2\/tags?post=59"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}