<?xml version="1.0" encoding="UTF-8"?>
<feed xml:lang="en-US" xmlns="http://www.w3.org/2005/Atom">
  <title>XyzzyB - techtips</title>
  <id>tag:www.xyzzyb.com,2008:mephisto/techtips</id>
  <generator version="0.7.3" uri="http://mephistoblog.com">Mephisto Noh-Varr</generator>
  <link href="http://www.xyzzyb.com/feed/techtips/atom.xml" rel="self" type="application/atom+xml"/>
  <link href="http://www.xyzzyb.com/techtips" rel="alternate" type="text/html"/>
  <updated>2008-05-25T14:41:01Z</updated>
  <entry xml:base="http://www.xyzzyb.com/">
    <author>
      <name>stephen</name>
    </author>
    <id>tag:www.xyzzyb.com,2008-05-19:367</id>
    <published>2008-05-19T20:35:00Z</published>
    <updated>2008-05-25T14:41:01Z</updated>
    <category term="quicklinks"/>
    <category term="techtips"/>
    <link href="http://www.xyzzyb.com/2008/5/19/connect-ssh-sessions-as-local-folders" rel="alternate" type="text/html"/>
    <title>Connect ssh sessions as local folders</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://minimaldesign.net/blog/workflow/remote-textmate-projects&quot; title=&quot;mac&quot;&gt;connect ssh directories as local folders&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.xyzzyb.com/">
    <author>
      <name>stephen</name>
    </author>
    <id>tag:www.xyzzyb.com,2008-05-15:359</id>
    <published>2008-05-15T19:32:00Z</published>
    <updated>2008-05-25T14:37:43Z</updated>
    <category term="learning"/>
    <category term="programming"/>
    <category term="quicklinks"/>
    <category term="techtips"/>
    <link href="http://www.xyzzyb.com/2008/5/15/javascript-video-lectures" rel="alternate" type="text/html"/>
    <title>Javascript Video Lectures</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://www.catonmat.net/blog/learning-javascript-programming-language-through-video-lectures/?stolen_from=hacker_news&quot;&gt;Javascript Video Lectures&lt;/a&gt;&lt;/p&gt;


	&lt;p&gt;The videos are extremely well done. I rank them right up there with the videos of Knuth lecturing about TeX for clarity and flow.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.xyzzyb.com/">
    <author>
      <name>stephen</name>
    </author>
    <id>tag:www.xyzzyb.com,2008-04-02:349</id>
    <published>2008-04-02T16:48:00Z</published>
    <updated>2008-05-25T14:33:27Z</updated>
    <category term="programming"/>
    <category term="quicklinks"/>
    <category term="techtips"/>
    <link href="http://www.xyzzyb.com/2008/4/2/php-logging-class" rel="alternate" type="text/html"/>
    <title>PHP Logging Class</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://urbanoalvarez.es/blog/2008/03/21/php-logging-class/&quot;&gt;&lt;span class=&quot;caps&quot;&gt;PHP&lt;/span&gt; logging class&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.xyzzyb.com/">
    <author>
      <name>stephen</name>
    </author>
    <id>tag:www.xyzzyb.com,2008-03-28:344</id>
    <published>2008-03-28T03:45:00Z</published>
    <updated>2008-09-02T13:58:12Z</updated>
    <category term="design"/>
    <category term="quicklinks"/>
    <category term="techtips"/>
    <link href="http://www.xyzzyb.com/2008/3/28/replacement-mspaint" rel="alternate" type="text/html"/>
    <title>Replacementing MSPaint</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://www.getpaint.net/&quot;&gt;Paint.NET is a free replacement to MSPaint that actually looks pretty decent&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.xyzzyb.com/">
    <author>
      <name>stephen</name>
    </author>
    <id>tag:www.xyzzyb.com,2008-02-05:206</id>
    <published>2008-02-05T22:58:00Z</published>
    <updated>2008-05-25T14:12:35Z</updated>
    <category term="learning"/>
    <category term="quicklinks"/>
    <category term="tech"/>
    <category term="techtips"/>
    <link href="http://www.xyzzyb.com/2008/2/5/install-opera-on-the-xo" rel="alternate" type="text/html"/>
    <title>Install Opera on the XO</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://xolaptophelp.com/index.php?topic=306.0&quot;&gt;How to install Opera on the XO laptop&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.xyzzyb.com/">
    <author>
      <name>stephen</name>
    </author>
    <id>tag:www.xyzzyb.com,2008-01-27:195</id>
    <published>2008-01-27T18:36:00Z</published>
    <updated>2008-09-06T19:38:36Z</updated>
    <category term="design"/>
    <category term="programming"/>
    <category term="techtips"/>
    <link href="http://www.xyzzyb.com/2008/1/27/rails-vs-django" rel="alternate" type="text/html"/>
    <title>Rails vs Django</title>
<content type="html">
            &lt;p&gt;After getting more into the depths of Django I was all set to write a comparison article, then I found one made by two guys who made the same website with both frameworks. Nicely written, lots of detail, objectively puts forward the strengths and weaknesses of both. Unfortunately the documents are not presented on a nicely written website, but in a subversion repository. I&#8217;ll put the links to the external resource first, but if those go away feel free to use the mirrored copy of the article below.&lt;/p&gt;


Rails vs. Django:
	&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://3columns.net/habitual/docs/&quot;&gt;Docs directory&lt;/a&gt;
	&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://3columns.net/habitual/docs/RailsVsDjango.pdf&quot;&gt;Rails vs. Django article&lt;/a&gt; [pdf, 132 KB]&lt;/li&gt;
		&lt;li&gt;&lt;a href=&quot;http://3columns.net/habitual/docs/Pres2.pdf&quot;&gt;Rails vs. Django presentation&lt;/a&gt; [pdf, 6.7 MB]&lt;/li&gt;
	&lt;/ul&gt;&lt;/li&gt;
	&lt;/ul&gt;


Local mirror:
	&lt;ul&gt;
	&lt;li&gt;&lt;a href=&quot;http://xyzzyb.com/assets/2008/1/27/RailsVsDjango.pdf&quot;&gt;Rails vs. Django article&lt;/a&gt;&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;While both frameworks do a great job of producing databases from their corresponding language code, my biggest complaint with Django is that it lacks a counterpart to Rails&#8217; migrations. Migrations enable a Rails projec to incrementally develop the database model. Essentially it&#8217;s subversion for the database structure. You build up changes (adding/removing/altering tables, columns, etc.) using &#8216;migrations&#8217; and can apply them or roll back at your whim. Django, on the other hand, really wants a fully formed database structure to start off the project. Any changes after the initial creation have to be shoehorned in by: 1) adding the stuctures to the database directly, then 2) updating the database model within Django…bleh!&lt;/p&gt;


	&lt;p&gt;Django is clearly designed to get sites with simple models up and running fast. Using it you can definitely feel its lineage as a rapid news story development framework. Rails feels more methodical, a framework for building many types of applications but with a corresponding increase in development time. But that&#8217;s just me. I&#8217;m much more familiar with the Ruby language and (as the Rails vs. Django article concludes) both frameworks are essentially equally capable, so go with the one that uses the language you know. There is a lot of awesome (and not so awesome) in Django and Rails.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.xyzzyb.com/">
    <author>
      <name>stephen</name>
    </author>
    <id>tag:www.xyzzyb.com,2008-01-25:194</id>
    <published>2008-01-25T07:30:00Z</published>
    <updated>2008-05-25T14:08:59Z</updated>
    <category term="essays"/>
    <category term="learning"/>
    <category term="programming"/>
    <category term="techtips"/>
    <link href="http://www.xyzzyb.com/2008/1/25/advantages-of-mvc" rel="alternate" type="text/html"/>
    <title>The advantages of MVC</title>
<content type="html">
            &lt;span class=&quot;caps&quot;&gt;MVC&lt;/span&gt; stands for &#8220;model-view-controller&#8221;, a programming paradigm where the application is split into three interconnected yet disparate parts (as interpreted by Django):
	&lt;ol&gt;
	&lt;li&gt;the &lt;strong&gt;model&lt;/strong&gt;: the &lt;em&gt;data&lt;/em&gt; of the application&lt;/li&gt;
		&lt;li&gt;the &lt;strong&gt;view&lt;/strong&gt;: the &lt;em&gt;presentation and selection&lt;/em&gt; of data to present to the user&lt;/li&gt;
		&lt;li&gt;the &lt;strong&gt;controller&lt;/strong&gt;: the &lt;em&gt;brains&lt;/em&gt; of the application that connects the user to the correct view&lt;/li&gt;
	&lt;/ol&gt;


	&lt;p&gt;Note, the &lt;span class=&quot;caps&quot;&gt;MVC&lt;/span&gt; paradigm is interpreted differently by the popular &#8220;Rails&#8221; framework (used for this very blog!). In Rails there are multiple controllers that decide what data to present to the user, and the view is left to &lt;em&gt;simply display&lt;/em&gt; the data. In this interpretation Django&#8217;s views would be seen as controllers, and Django&#8217;s templates would be views.&lt;/p&gt;


	&lt;p&gt;To best describe how &lt;span class=&quot;caps&quot;&gt;MVC&lt;/span&gt; helps us do our jobs as web programmers better, lets look at a simple &lt;span class=&quot;caps&quot;&gt;PHP&lt;/span&gt; webpage application written as a script:&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
&amp;lt;?php

$page_title = &quot;Ten most recent blog entries&quot;;

include_once($include_path.'/header.php');

// setup $db
include_once($include_path.'/db_connection_for_this_application.php');

$recent_blog_posts = mysql_query(&quot;SELECT 
  posts.post_date, 
  posts.post_title, 
  posts.post_content 
FROM 
  posts
WHERE 
  posts.post_status='publish'
ORDER BY posts.post_date DESC LIMIT 10, $db);

echo '&amp;lt;h1&amp;gt;Recent Posts&amp;lt;/h1&amp;gt;';
while($posts_data = mysql_fetch_array($recent_blog_posts)) {
  echo '&amp;lt;div class=&quot;post&quot;&amp;gt;';
  echo '&amp;lt;div class=&quot;blog_date&quot;&amp;gt;' . $posts_data['post_date'] . &quot;&amp;lt;/div&amp;gt;\n&quot;;
  echo '&amp;lt;div class=&quot;blog_entry_title&quot;&amp;gt;' . $posts_data['post_title'] . &quot;&amp;lt;/div&amp;gt;\n&quot;;
  echo '&amp;lt;div class=&quot;blog_entry&quot;&amp;gt;' . $posts_data['post_content'] . &quot;&amp;lt;/div&amp;gt;\n&quot;;
  echo '&amp;lt;/div&amp;gt;';
}

include_once($include_path.'/footer.php');

?&amp;gt;
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Simple enough. That&#8217;s actually the big advantage of writing web applications as scripts. They are (almost) entirely self-contained and easy to understand. You start reading at the top and finish at the bottom, with no file jumping or object modeling required.&lt;/p&gt;


Unfortunately, this simpliciy is also very limiting:
	&lt;ul&gt;
	&lt;li&gt;&lt;strong&gt;The content and the programming are combined.&lt;/strong&gt; This means that, aside from &lt;span class=&quot;caps&quot;&gt;CSS&lt;/span&gt;, if any web &lt;em&gt;designers&lt;/em&gt; want to update the look of the page then they&#8217;ll have to modify the same file that contains the application. That&#8217;s a great opportunity for things to go wrong.&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;The header and footer are fixed&lt;/strong&gt;. This means altering something like the title of the page forces the application to declare prespecified variables (e.g. the $page_title), that the header file assumes are in place. A bunch of these variables can quickly clutter an application. At a simple level, including headers and footers makes sense, but as pages get more complex they get harder to maintain. What if you have a standard header/footer, but want slightly modified versions for other sections? Using header/footer includes means that you&#8217;ll have to create separate include files for each. Without a clear organizational structure things can get confusing pretty quickly.&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;Low-level programming is involved.&lt;/strong&gt; The programmer has to build database queries by hand, which is a great place for bugs to hide.&lt;/li&gt;
		&lt;li&gt;&lt;strong&gt;No object oriented programming.&lt;/strong&gt; You can&#8217;t wrap up functions and data into logical blocks with specific interfaces (e.g. objects). In a better system, we&#8217;d just ask the &#8220;Blog&#8221; object directly for the ten most recent posts with something like {{ blog.posts | &#8216;limit&#8217;: 10 }}&lt;/li&gt;
	&lt;/ul&gt;


	&lt;p&gt;As you can see, there is room for something better. That something is an &lt;span class=&quot;caps&quot;&gt;MVC&lt;/span&gt; framework such as Django or Rails. Let&#8217;s look at how one (Django) solves the problems with our &lt;span class=&quot;caps&quot;&gt;PHP&lt;/span&gt; script. I&#8217;ll show you the code first, then get into the explanation:&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
### models.py (the *model*) ###

from django.db import models

class Blog(models.Model):
    entry_title = models.CharField(maxlength=50)
    blog_date = models.DateField()
    entry = models.TextField()

### views.py (the *view*) ###

from django.shortcuts import render_to_response
from models import Blog

def recent_posts(request):
    post_list = Blog.objects.order_by('-blog_date')[:10]
    return render_to_response('recent_posts.html', {'post_list': post_list})

### urls.py (the *controller*) ###

from django.conf.urls.defaults import *
import views

urlpatterns = patterns('',
    (r'^recent/$', views.recent_posts),
)

### recent_posts.html (the *template* (part of the view))###

&amp;lt;html&amp;gt;&amp;lt;head&amp;gt;&amp;lt;title&amp;gt;Recent Blog Posts&amp;lt;/title&amp;gt;&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
&amp;lt;h1&amp;gt;Recent Posts&amp;lt;/h1&amp;gt;
{% for post in post_list %}
&amp;lt;div class=&quot;post&quot;&amp;gt;
  &amp;lt;div class=&quot;blog_date&quot;&amp;gt;{{blog_date}}&amp;lt;/div&amp;gt;
  &amp;lt;div class=&quot;blog_entry_title&quot;&amp;gt;{{entry title}}&amp;lt;/div&amp;gt;
  &amp;lt;div class=&quot;blog_entry&quot;&amp;gt;{{entry}}&amp;lt;/div&amp;gt;
{% endfor %}
&amp;lt;/body&amp;gt;&amp;lt;/html&amp;gt;
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;Ok! That seems a little confusing compared to the script doesn&#8217;t it? Let&#8217;s dive in:&lt;/p&gt;


	&lt;h3&gt;recent_posts.html&lt;/h3&gt;


	&lt;p&gt;Take a closer look at the &#8220;recent_posts.html&#8221;. Think of how lucidly clear that file is to a web designer? There&#8217;s hardly any code! While of course no templating language can eliminate programming constructs Django&#8217;s system does a great job of only giving the template designers what they need to get the job done. The template &#8220;programming&#8221; is using its own programming language, not straight Python. There are two big reasons for this: 1) the language is meant to be simple and only provide the features needed to select or present the proper data, 2) the language doesn&#8217;t allow templates to do anything that the application should handle (e.g. a template can&#8217;t tell the database to delete itself).&lt;/p&gt;


	&lt;p&gt;Yes, my example doesn&#8217;t demonstrate how Django helps with header/footer includes, that&#8217;s coming up so be patient!&lt;/p&gt;


	&lt;h3&gt;models.py&lt;/h3&gt;


	&lt;p&gt;This is simply describing to Django how to organize the data object that we&#8217;ll be dealing with.&lt;/p&gt;


	&lt;h3&gt;urls.py&lt;/h3&gt;


	&lt;p&gt;This is routing a user&#8217;s request for the web address &#8216;recent/&#8217; (e.g. mysite.com/recent) to the recent_posts function in views.py.&lt;/p&gt;


	&lt;h3&gt;views.py&lt;/h3&gt;


	&lt;p&gt;This is the best part, take a look again:&lt;/p&gt;


&lt;pre&gt;
&lt;code&gt;
def recent_posts(request):
    post_list = Blog.objects.order_by('-blog_date')[:10]
    return render_to_response('recent_posts.html', {'post_list': post_list})
&lt;/code&gt;
&lt;/pre&gt;

	&lt;p&gt;That&#8217;s it? That&#8217;s it! Our complex &lt;span class=&quot;caps&quot;&gt;SQL&lt;/span&gt; query is now a higher level abstraction where we tell Django to tell the blog to give us the latest ten posts. Done!&lt;/p&gt;


	&lt;p&gt;Now lets look at that last piece: header/footer files.&lt;/p&gt;


	&lt;p&gt;Django does allow us to build templates that pull in header/footer includes, but it also lets us solve the common data problem with &lt;strong&gt;template inheritance&lt;/strong&gt;. With template inheritance we don&#8217;t abstract the pieces of our web pages that are the same, we pull out the pieces that are &lt;em&gt;different&lt;/em&gt;. Let me explain with a very simple webpage:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
&amp;lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01//EN&quot;&amp;gt;
&amp;lt;html lang=&quot;en&quot;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;My Website&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;Page Title&amp;lt;/h1&amp;gt;
    &amp;lt;p&amp;gt;Customized content!&amp;lt;/p&amp;gt;

    &amp;lt;hr&amp;gt;
    &amp;lt;p&amp;gt;This is my footer&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Done using header/footer includes:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
### header include file ###
&amp;lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01//EN&quot;&amp;gt;
&amp;lt;html lang=&quot;en&quot;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;My Website&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;

### footer include file ###
&amp;lt;p&amp;gt;This is my footer&amp;lt;/p&amp;gt;
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

### custom page ###
include(header_file)

&amp;lt;h1&amp;gt;Page Title&amp;lt;/h1&amp;gt;
&amp;lt;p&amp;gt;Customized content!&amp;lt;/p&amp;gt;

include(footer_file)
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;Now done with Django&#8217;s template inheritence:&lt;/p&gt;


&lt;pre&gt;&lt;code&gt;
### base.html ###
&amp;lt;!DOCTYPE HTML PUBLIC &quot;-//W3C//DTD HTML 4.01//EN&quot;&amp;gt;
&amp;lt;html lang=&quot;en&quot;&amp;gt;
&amp;lt;head&amp;gt;
    &amp;lt;title&amp;gt;{% block title %}My Website{% endblock %}&amp;lt;/title&amp;gt;
&amp;lt;/head&amp;gt;
&amp;lt;body&amp;gt;
    &amp;lt;h1&amp;gt;{% block pagetitle %}{% endblock %}&amp;lt;/h1&amp;gt;
    {% block content %}{% endblock %}
    {% block footer %}
    &amp;lt;p&amp;gt;This is my footer.&amp;lt;/p&amp;gt;
    {% endblock %}
&amp;lt;/body&amp;gt;
&amp;lt;/html&amp;gt;

### page.html ###
{% extends &quot;base.html&quot; %}

{% block title %}Customized Title!{% endblock %}

{% block pagetitle %}Customized page title!{% endblock %}
{% block content %}
&amp;lt;p&amp;gt;Customized content!&amp;lt;/p&amp;gt;
{% endblock %}
&lt;/code&gt;&lt;/pre&gt;

	&lt;p&gt;See what we did there? The parts of the page that will &lt;strong&gt;change&lt;/strong&gt; are pulled out of the base. Django&#8217;s template system lets you declare &#8220;blocks&#8221; that indicate that that part of the page &lt;em&gt;may&lt;/em&gt; change. If an extending template declares a block that matches that of the parent template, then the parent&#8217;s block is overwritten. If a block isn&#8217;t declared by the sub-page, that is in the parent page then the parent page&#8217;s block is used. Notice in our &#8220;page.html&#8221; the footer isn&#8217;t discussed at all. Django sees that we are &#8220;extending&#8221; base.html and that we haven&#8217;t specified our own footer block so it defaults to the footer block that was in base.html.&lt;/p&gt;


	&lt;p&gt;Perfect! We can create base templates that allow for child pages to overwrite &lt;strong&gt;any part that we explicitly allow&lt;/strong&gt;! No more locked headers or footers!&lt;/p&gt;


	&lt;p&gt;Templates can go through multiple levels of inheritence as well. We could easily have a base template that is then extended into &#8220;section&#8221; templates that are then extended to specific pages. With a clear and logical chain of command it is easy to see how the webpage templates work together. Much better than a couple dozen header/footer files lying around. We get all the advantages of reusing designs without the headaches!&lt;/p&gt;


	&lt;p&gt;So there you have it. Sorry for the rambling/unedited nature of this post. It&#8217;s 2:30am, I can&#8217;t sleep, but I felt like sharing.&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.xyzzyb.com/">
    <author>
      <name>stephen</name>
    </author>
    <id>tag:www.xyzzyb.com,2008-01-20:172</id>
    <published>2008-01-20T16:52:00Z</published>
    <updated>2008-05-25T14:13:19Z</updated>
    <category term="learning"/>
    <category term="quicklinks"/>
    <category term="tech"/>
    <category term="techtips"/>
    <link href="http://www.xyzzyb.com/2008/1/20/how-to-install-ubuntu-on-the-xo" rel="alternate" type="text/html"/>
    <title>How to install Ubuntu on the XO</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://olpcnews.com/forum/index.php?topic=1436.0&quot;&gt;How to install Ubuntu on the XO&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.xyzzyb.com/">
    <author>
      <name>stephen</name>
    </author>
    <id>tag:www.xyzzyb.com,2007-12-10:110</id>
    <published>2007-12-10T19:30:00Z</published>
    <updated>2008-05-24T16:40:55Z</updated>
    <category term="design"/>
    <category term="techtips"/>
    <link href="http://www.xyzzyb.com/2007/12/10/designing-a-report-discussion-wiki" rel="alternate" type="text/html"/>
    <title>Designing a Report Discussion Wiki</title>
<content type="html">
            &lt;p&gt;I was recently tasked with converted a large document into an easily commentable wiki using mediawiki. Here&#8217;s how I did it:&lt;/p&gt;


	&lt;h3&gt;Start an article using one or more headers to organize content.&lt;/h3&gt;


&lt;pre&gt;
  (article)
  == Header 1 ==
  Content content content.
  == Header 2 ==
  More content.
&lt;/pre&gt;

	&lt;h3&gt;Mirror the headers in the discussion page&lt;/h3&gt;


&lt;pre&gt;
  (discussion)
  == Header 1 ==
  == Header 2 ==
&lt;/pre&gt;

	&lt;p&gt;Now, notice that each header in the discussion page has its own edit button. We are going to use this to add an &#8216;add comment&#8217; link to each header in the article. To do this we&#8217;ll have to go pass two arguments to a full weblink: action=edit, and section=(the appropriate section number). The section numbers start with 1 for the first header and increment up. To make this link as generic as possible we&#8217;ll use mediawiki variables to construct the link:&lt;/p&gt;


	&lt;h3&gt;Add an &#8216;Add Comment&#8217; link from the article to the corresponding section of the discussion page&lt;/h3&gt;


&lt;pre&gt;[{{fullurl:Talk:{{PAGENAME}}|action=edit&#38;section=1}} Add Comment]&lt;/pre&gt;

	&lt;p&gt;Add this text wherever you&#8217;d like the &#8216;Add Comment&#8217; link on the article page. I found that after the content of each article works well. So we end up with this:&lt;/p&gt;


&lt;pre&gt;
  (article)
  == Header 1 ==
  Content content content.
[{{fullurl:Talk:{{PAGENAME}}|action=edit&#38;section=1}} Add Comment]
  == Header 2 ==
  More content.
[{{fullurl:Talk:{{PAGENAME}}|action=edit&#38;section=2}} Add Comment]
&lt;/pre&gt;

	&lt;p&gt;Now when users click &#8216;Add Comment&#8217; on the article, they are taken straight to an editing view of the corresponding section of discussion page. Easy!&lt;/p&gt;
          </content>  </entry>
  <entry xml:base="http://www.xyzzyb.com/">
    <author>
      <name>stephen</name>
    </author>
    <id>tag:www.xyzzyb.com,2007-12-04:109</id>
    <published>2007-12-04T16:55:00Z</published>
    <updated>2008-05-24T16:40:30Z</updated>
    <category term="quicklinks"/>
    <category term="tech"/>
    <category term="techtips"/>
    <link href="http://www.xyzzyb.com/2007/12/4/waterroof" rel="alternate" type="text/html"/>
    <title>WaterRoof</title>
<content type="html">
            &lt;p&gt;&lt;a href=&quot;http://www.hanynet.com/waterroof/&quot;&gt;WaterRoof: firewall management for &lt;span class=&quot;caps&quot;&gt;OS X&lt;/span&gt;&lt;/a&gt;&lt;/p&gt;
          </content>  </entry>
</feed>
