<?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>Death of a Gremmie &#187; markitup</title>
	<atom:link href="http://deathofagremmie.com/tag/markitup/feed/" rel="self" type="application/rss+xml" />
	<link>http://deathofagremmie.com</link>
	<description>by Brian Neal</description>
	<lastBuildDate>Wed, 14 Jul 2010 02:31:19 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0</generator>
		<item>
		<title>Member Map Part 2</title>
		<link>http://deathofagremmie.com/2009/02/14/member-map-part-2/</link>
		<comments>http://deathofagremmie.com/2009/02/14/member-map-part-2/#comments</comments>
		<pubDate>Sat, 14 Feb 2009 22:10:30 +0000</pubDate>
		<dc:creator>gremmie</dc:creator>
				<category><![CDATA[SG101 2.0]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[markitup]]></category>
		<category><![CDATA[membermap]]></category>

		<guid isPermaLink="false">http://deathofagremmie.com/?p=157</guid>
		<description><![CDATA[I&#8217;ve gotten the Member Map application ported to my Django powered site now. This was pretty straightforward and a lot of fun because of the Javascript aspect. Let me address the points I made in part 1 of this post, below. Leveraging jQuery. I did make use of jQuery for the client side Javascript. This [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve gotten the Member Map application ported to my Django powered site now. This was pretty straightforward and a lot of fun because of the Javascript aspect. Let me address the points I made in <a href="http://deathofagremmie.com/2009/02/06/member-map-part-1/">part 1</a> of this post, below.</p>
<ol>
<li>Leveraging <a href="http://jquery.com/">jQuery</a>. I did make use of jQuery for the client side Javascript. This really did simplify things. In the old version of the code, I had a 282 line Javascript file. The new version weighs in at 161 lines, which is 57% the size of the earlier version.</li>
<li>Use of JSON encoder library. It turns out that Django includes a version of the <a href="http://www.undefined.org/python/">simplejson</a> library already. This is used in Django&#8217;s serialization feature. I probably could have used this feature, but I didn&#8217;t need to serialize an entire model, and wanted to rename some of the fields. So I simply did a &#8220;import django.utils.simplejson as json&#8221; and went to town. My server side code was now much simpler than the previous version where I encoded by hand.</li>
<li>I did continue to use the <a href="http://markitup.jaysalvat.com/home/">markItUp</a>! editor to let users edit their message to go along with their location. I learned that the size of the editor is easily adjusted through the use of CSS. So I was able to override the default size of the editor by including my own CSS style sheet below the default sheet.</li>
<li>Reducing complexity. Here is where it got interesting. I decided to add a &#8220;json&#8221; field to the MapEntry model. This field is populated whenever a model object is saved by providing my own save() method. Inside my save() I use Django&#8217;s template render_to_string() to render the HTML  message that appears in the pop-up balloon on the map. This consists  of the user&#8217;s avatar followed by a message that is marked up in <a href="http://daringfireball.net/projects/markdown/">Markdown</a>. I then build a JSON representation of the MapEntry using Django&#8217;s simplejson. This representation consists of the following fields: name, location, latitude, longitude, and the HTML message. By pre-saving all of this information, it makes it much more efficient to retrieve 200+ users&#8217; information when the map is first loaded. In the view function, I make use of the values_list() queryset method to retrieve all the json fields. I don&#8217;t need the ORM to convert each MapEntry to an actual Python object.</li>
</ol>
<p>Another thing I did differently for the port was when a user updates or adds their position on the map, I don&#8217;t reload the entire map. I just adjust their information to reduce bandwidth with an AJAX post. I&#8217;m not sure why I didn&#8217;t do this before, perhaps because it was to tedious to do without jQuery. It was just easier to reload the whole thing.</p>
<p>This was all well and cool, doing all this pre-computation, but what happens when a user changes her avatar? Her entry on the map will likely have a broken graphic. No problem. Here I took advantage of <a href="http://docs.djangoproject.com/en/dev/topics/signals/">Django&#8217;s signals</a>. I attached a signal handler to listen for changes to the UserProfile model. Whenever the UserProfile is saved, my signal handler runs and re-saves the corresponding MapEntry to regenerate the JSON. Very slick.</p>
<p>And finally, another thing that I learned about Django was that simple_tags can have defaulted arguments. I added an argument to my avatar tag so that I could apply CSS to the generated HTML img tag if needed. In the Member Map pop-up balloon, it looked nicer if the avatar was floated to the left.</p>
<p>So all and all, again, I&#8217;m very happy with how easy Django makes writing an application like this. Using jQuery was also a big productivity booster.</p>
<p>Here are some screenshots. You can also see the new <a href="http://www.blueprintcss.org/">Blueprints CSS</a> in action as well.</p>
<div id="attachment_159" class="wp-caption alignnone" style="width: 310px"><a href="http://deathofagremmie.com/wp-content/uploads/2009/02/member_map1.png"><img class="size-medium wp-image-159" title="member_map1" src="http://deathofagremmie.com/wp-content/uploads/2009/02/member_map1-300x187.png" alt="Member Map" width="300" height="187" /></a><p class="wp-caption-text">Member Map 1</p></div>
<div id="attachment_160" class="wp-caption alignnone" style="width: 310px"><a href="http://deathofagremmie.com/wp-content/uploads/2009/02/member_map2.png"><img class="size-medium wp-image-160" title="member_map2" src="http://deathofagremmie.com/wp-content/uploads/2009/02/member_map2-300x187.png" alt="Member Map" width="300" height="187" /></a><p class="wp-caption-text">Member Map 2</p></div>
]]></content:encoded>
			<wfw:commentRss>http://deathofagremmie.com/2009/02/14/member-map-part-2/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Member Map Part 1</title>
		<link>http://deathofagremmie.com/2009/02/06/member-map-part-1/</link>
		<comments>http://deathofagremmie.com/2009/02/06/member-map-part-1/#comments</comments>
		<pubDate>Sat, 07 Feb 2009 00:39:44 +0000</pubDate>
		<dc:creator>gremmie</dc:creator>
				<category><![CDATA[SG101 2.0]]></category>
		<category><![CDATA[django]]></category>
		<category><![CDATA[jquery]]></category>
		<category><![CDATA[json]]></category>
		<category><![CDATA[markitup]]></category>
		<category><![CDATA[membermap]]></category>

		<guid isPermaLink="false">http://deathofagremmie.com/?p=154</guid>
		<description><![CDATA[I started working on the Member Map application last weekend. This will be a port of the PHP-Nuke module I wrote, which you can find here. In a nutshell, this application displays a Google Map on your site, and allows site members to place markers representing their location on the map. If you click on [...]]]></description>
			<content:encoded><![CDATA[<p>I started working on the Member Map application last weekend. This will be a port of the PHP-Nuke module I wrote, which you can find <a title="Member Map for PHP-Nuke" href="https://sourceforge.net/projects/membermapnuke/">here</a>. In a nutshell, this application displays a <a title="Google Maps API" href="http://code.google.com/apis/maps/">Google Map</a> on your site, and allows site members to place markers representing their location on the map. If you click on a marker, a balloon pops up which displays the user&#8217;s avatar, a link to their profile, and a short message that they have typed previously. The Nuke version of this application is a big hit on the current site, and last time I checked, we had over 220 members on the map.</p>
<p>The existing application consists of the PHP-Nuke code, written in PHP, on the server side, and a fair amount of Javascript on the client side. All interaction with Google Maps is done through the Javascript code.</p>
<p>For the port to Django, I want to do a couple of things different.</p>
<ol>
<li>Leverage <a title="jQuery" href="http://jquery.com/">jQuery</a> in the client-side Javascript. The existing version was written before I was aware of Javascript libraries, and it is all &#8220;vanilla&#8221; Javascript. By using jQuery, the amount of code I have to write will be much smaller. And by taking advantage of jQuery, it should be more portable and browser robust.</li>
<li>On the server side, the existing application did not use any <a title="JSON" href="http://json.org">JSON</a> encoder library. I simply constructed the JSON by hand. I can&#8217;t remember why I did this. I think it was partly because I didn&#8217;t know any better, and partly because the PHP version I had on the original hosting server may not have had it. I will explore what Python and/or Django options exist.</li>
<li>I&#8217;ll leverage the <a href="http://markitup.jaysalvat.com/home/">markItUp</a>! editor that I&#8217;ve been using for comments to let the users enter <a href="http://daringfireball.net/projects/markdown/">Markdown</a> comments. I&#8217;ve used this in the last couple of apps I&#8217;ve written and it will be easy to implement. The only concern with doing this is the user may be tempted to write a lot more than in the older app, and it may make for large &#8220;balloons&#8221;. We&#8217;ll see.</li>
<li>I want to make the new application less database and computationally intense than the older version. I don&#8217;t have any problems running the current version with 200 users, but I think I could do it a bit smarter this time around. This means I am going to try to save marked up and JSON encoded strings in the database rather than compute them on every page load. I am also wary of instantiating 200+ map entry model objects with the Django ORM (albeit in a loop) just to generate the JSON. Luckily Django lets you use raw SQL when needed. But in this case I think a simple use of the values() method will really be useful here.</li>
</ol>
<p>So, those are my going in goals. I&#8217;ve already started working on this, and I&#8217;ve learned a lot so far. In the next post or two I will detail the progress and what problems I ran into.</p>
]]></content:encoded>
			<wfw:commentRss>http://deathofagremmie.com/2009/02/06/member-map-part-1/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
		<item>
		<title>Update on Comments and CSS Woes</title>
		<link>http://deathofagremmie.com/2009/01/14/update-on-comments-and-css-woes/</link>
		<comments>http://deathofagremmie.com/2009/01/14/update-on-comments-and-css-woes/#comments</comments>
		<pubDate>Thu, 15 Jan 2009 00:55:46 +0000</pubDate>
		<dc:creator>gremmie</dc:creator>
				<category><![CDATA[SG101 2.0]]></category>
		<category><![CDATA[comments]]></category>
		<category><![CDATA[css]]></category>
		<category><![CDATA[markitup]]></category>
		<category><![CDATA[sg101]]></category>

		<guid isPermaLink="false">http://deathofagremmie.com/?p=131</guid>
		<description><![CDATA[I&#8217;ve made good progress on the comments system, and I&#8217;m glad I took the time to roll my own. I have a nice AJAX style commenting system integrated with the markItUp! editor. I&#8217;m allowing comments to be marked up with Markdown, and I&#8217;m very happy with it. Having the ability for users to easily post [...]]]></description>
			<content:encoded><![CDATA[<p>I&#8217;ve made good progress on the comments system, and I&#8217;m glad I took the time to roll my own. I have a nice AJAX style commenting system integrated with the <a href="http://markitup.jaysalvat.com/home/">markItUp! editor</a>. I&#8217;m allowing comments to be marked up with <a href="http://daringfireball.net/projects/markdown/">Markdown</a>, and I&#8217;m very happy with it. Having the ability for users to easily post links and images will be a big improvement from the existing site&#8217;s commenting systems.  I need to cut the private messages application over to markItUp instead of <a href="http://tinymce.moxiecode.com/">TinyMCE</a>. I think TinyMCE is a bit overkill for anything except news stories. I also added the ability for users to &#8220;flag&#8221; comments for spam or abuse.</p>
<p>The markItUp editor is very nice, and I was even able to add a drop-down menu for my smiley system. Now one can click on a smiley from the editor and get it added to the comment! The markItUp editor has a slick preview system, which can use AJAX to post what the user has typed so far and get an HTML response. The only drawback is I can&#8217;t easily clear or hide the preview pane once the comment has been posted by AJAX. So you are left with a blank editor ready for the next comment, but the preview pane is still showing whatever you previewed last. This is minor, I think, and I&#8217;ve already made the author aware of this issue. He told me he will look into it for the next release. I highly recommend markItUp.</p>
<p>And finally I took a cue from <a href="http://www.pointy-stick.com/blog/">Malcom Tredinnick&#8217;s blog</a> (the Django source is available for study &#8211; Thanks Malcom!). I added a field to the comments table to store the rendered HTML for each comment. This field is updated on each comment object&#8217;s save. This will save processing time to convert the Markdown markup to HTML. Since comments are viewed many, many times compared to how often they are edited, this seemed like a sensible optimization at the expense of some disk space.</p>
<p>I need to add comments to the other parts of the system I have developed already (news, polls, etc.). However I&#8217;m being distracted at the moment by a problem I am having with CSS. This has been bugging me for months now. I don&#8217;t know why it happens, but I&#8217;m seeing &lt;div&gt; tags in a left floating &lt;div&gt; affect &lt;div&gt; tags in my main content area. Large gaps get created. It seems that I may be trying too hard to duplicate the PHP-Nuke blocks, and nesting lots of divs seems to be very fragile. I think I might have to investigate a different CSS layout and redo my base template. I&#8217;m googling various CSS layout tutorials in my spare time. I don&#8217;t want to become an expert in this, but I need something simple that looks decent. I wish I had a web designer to help me out with this part.</p>
]]></content:encoded>
			<wfw:commentRss>http://deathofagremmie.com/2009/01/14/update-on-comments-and-css-woes/feed/</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>
