Index: branches/htmlform/cgi-bin/main.cgi
===================================================================
--- branches/htmlform/cgi-bin/main.cgi	(revision 451)
+++ branches/htmlform/cgi-bin/main.cgi	(revision 456)
@@ -580,99 +580,97 @@
   }
 
-  my $html;
+  # hack pthbttt eww
+  $webvar{block} = '' if !$webvar{block};
+
+# hmm.  TMPL_IF block and TMPL_ELSE block on these instead?
+  $page->param(rowa => 'row'.($webvar{block} eq '' ? 1 : 0));
+  $page->param(rowb => 'row'.($webvar{block} eq '' ? 0 : 1));
+  $page->param(block => $webvar{block});	# fb-assign flag, if block is set, we're in fb-assign
+  $page->param(iscontained => ($webvar{fbtype} && $webvar{fbtype} ne 'y'));
 
   # New special case- block to assign is specified
   if ($webvar{block} ne '') {
-    open HTML, "../fb-assign.html"
-	or croak "Could not open fb-assign.html: $!";
-    $html = join('',<HTML>);
-    close HTML;
     my $block = new NetAddr::IP $webvar{block};
-    $html =~ s|\$\$BLOCK\$\$|$block|g;
-    $html =~ s|\$\$MASKBITS\$\$|$block->masklen|;
-    my $typelist = '';
-
+
+    # Handle contained freeblock allocation.
     # This is a little dangerous, as it's *theoretically* possible to
     # get fbtype='n' (aka a non-routed freeblock).  However, should
     # someone manage to get there, they get what they deserve.
     if ($webvar{fbtype} ne 'y') {
-      # Snag the type of the block from the database.  We have no
-      # convenient way to pass this in from the calling location.  :/
+      # Snag the type of the container block from the database.
       $sth = $ip_dbh->prepare("select type from allocations where cidr >>='$block'");
       $sth->execute;
       my @data = $sth->fetchrow_array;
       $data[0] =~ s/c$/r/;	# Munge the type into the correct form
-      $typelist = "$list_alloctypes{$data[0]}<input type=hidden name=alloctype value=$data[0]>\n";
+      $page->param(fbdisptype => $list_alloctypes{$data[0]});
+      $page->param(type => $data[0]);
     } else {
-      $typelist .= qq(<select name="alloctype">\n);
       $sth = $ip_dbh->prepare("select type,listname from alloctypes where listorder < 500 ".
 	"and type not like '_i' and type not like '_r' order by listorder");
       $sth->execute;
       my @data = $sth->fetchrow_array;
-      $typelist .= "<option value='$data[0]' selected>$data[1]</option>\n";
+      my @typelist;
+      my $selflag = 0;
       while (my @data = $sth->fetchrow_array) {
-        $typelist .= "<option value='$data[0]'>$data[1]</option>\n";
+        my %row = (tval => $data[0],
+                type => $data[1],
+                sel => ($selflag == 0 ? ' selected' : '')
+                );
+        push (@typelist, \%row);
+        $selflag++;
       }
-      $typelist .= "</select>\n";
-    }
-    $html =~ s|\$\$TYPELIST\$\$|$typelist|g;
+      $page->param(typelist => \@typelist);
+    }
   } else {
-    open HTML, "../assign.html"
-	or croak "Could not open assign.html: $!";
-    $html = join('',<HTML>);
-    close HTML;
-    my $masterlist = "<select name=allocfrom><option selected>-</option>\n";
+    my @masterlist;
     foreach my $master (@masterblocks) {
-      $masterlist .= "<option>$master</option>\n";
-    }
-    $masterlist .= "</select>\n";
-    $html =~ s|\$\$MASTERLIST\$\$|$masterlist|g;
-    my $pops = '';
+      my %row = (master => "$master");
+      push (@masterlist, \%row);
+    }
+    $page->param(masterlist => \@masterlist);
+
+    my @pops;
     foreach my $pop (@poplist) {
-      $pops .= "<option>$pop</option>\n";
-    }
-    $html =~ s|\$\$POPLIST\$\$|$pops|g;
-    my $typelist = '';
-    $sth = $ip_dbh->prepare("select type,listname from alloctypes where listorder < 900 order by listorder");
+      my %row = (pop => $pop);
+      push (@pops, \%row);
+    }
+    $page->param(pops => \@pops);
+
+    # could arguably include routing (500) in the list, but ATM it doesn't
+    # make sense, and in any case that shouldn't be structurally possible here.
+    $sth = $ip_dbh->prepare("select type,listname from alloctypes where listorder < 500 order by listorder");
     $sth->execute;
-    my @data = $sth->fetchrow_array;
-    $typelist .= "<option value='$data[0]' selected>$data[1]</option>\n";
+    my @typelist;
+    my $selflag = 0;
     while (my @data = $sth->fetchrow_array) {
-      $typelist .= "<option value='$data[0]'>$data[1]</option>\n";
-    }
-    $html =~ s|\$\$TYPELIST\$\$|$typelist|g;
-  }
-  my $cities = '';
+      my %row = (tval => $data[0],
+        type => $data[1],
+        sel => ($selflag == 0 ? ' selected' : '')
+        );
+      push (@typelist, \%row);
+      $selflag++;
+    }
+    $page->param(typelist => \@typelist);
+  }
+
+  my @cities;
   foreach my $city (@citylist) {
-    $cities .= "<option>$city</option>\n";
-  }
-  $html =~ s|\$\$ALLCITIES\$\$|$cities|g;
+    my %row = (city => $city);
+    push (@cities, \%row);
+  }
+  $page->param(citylist => \@cities);
 
 ## node hack
   $sth = $ip_dbh->prepare("SELECT node_id, node_name FROM nodes ORDER BY node_type,node_id");
   $sth->execute() or print "DEBUG: failed retrieval from nodes: ".$sth->errstr,"<br>\n";
-  my $nodes = '';
+  my @nodes;
   while (my ($nid,$nname) = $sth->fetchrow_array()) {
-    $nodes .= "<option value='$nid'>$nname</option>\n";
-  }
-  $html =~ s/\$\$NODELIST\$\$/$nodes/;
+    my %row = (nid => $nid, nname => $nname);
+    push (@nodes, \%row);
+  }
+  $page->param(nodelist => \@nodes);
 ## end node hack
 
-  my $i = 0;
-  $i++ if $webvar{fbtype} eq 'y';
-  # Check to see if user is allowed to do anything with sensitive data
-  my $privdata = '';
-  if ($IPDBacl{$authuser} =~ /s/) {
-    $privdata = qq(<tr class="color).($i%2).qq("><td>Restricted data:</td>).
-        qq(<td class=regular><textarea rows="3" cols="64" name="privdata" class="regular">).
-        qq(</textarea></td></tr>\n);
-    $i++;
-  }
-  $html =~ s/\$\$PRIVDATA\$\$/$privdata/g;
-
-  $i = $i % 2;
-  $html =~ s/\$\$BUTTONROWCOLOUR\$\$/color$i/;
-
-  print $html;
+  $page->param(privdata => $IPDBacl{$authuser} =~ /s/);
 
 } # assignBlock
Index: branches/htmlform/ipdb.css
===================================================================
--- branches/htmlform/ipdb.css	(revision 451)
+++ branches/htmlform/ipdb.css	(revision 456)
@@ -155,4 +155,10 @@
 }
 
+.tblsubtitle {
+        font-size: 105%;
+        font-weight: bold;
+        font-family: Verdana, Arial, Helvetica, sans-serif;
+}
+
 .small {
 	font-size: 60%;
Index: branches/htmlform/templates/assign.tmpl
===================================================================
--- branches/htmlform/templates/assign.tmpl	(revision 456)
+++ branches/htmlform/templates/assign.tmpl	(revision 456)
@@ -0,0 +1,120 @@
+<div class="indent">
+<TMPL_IF NAME=block>
+<div class="tblsubtitle">
+Assign free <TMPL_IF NAME=iscontained><TMPL_VAR NAME=fbdisptype></TMPL_IF> block <TMPL_VAR NAME=block>
+</div>
+<TMPL_ELSE>
+<div class="tblsubtitle">Assign IPs</div>
+</TMPL_IF>
+<br>
+
+<table class="regular" cellspacing="1" cellpadding="1">
+<form method="POST" action="main.cgi" class="regular">
+
+<tr class="row0">
+<td>Customer location:&nbsp;</td>
+<td>
+<select name="city"><option selected>-</option>
+<TMPL_LOOP NAME=citylist><option><TMPL_VAR NAME=city></option></TMPL_LOOP>
+</select>
+&nbsp;<a href="javascript:popNotes('/ip/newcity.html')">Add new location</a>
+</td>
+</tr>
+
+<tr class="row1">
+<td>Allocation type:</td>
+<td>
+<TMPL_IF NAME=iscontained>
+<TMPL_VAR NAME=fbdisptype><input type="hidden" name="alloctype" value="<TMPL_VAR NAME=type>">
+<TMPL_ELSE>
+<select>
+<TMPL_LOOP name=typelist>
+	<option value="<TMPL_VAR NAME=tval>"<TMPL_VAR NAME=sel>><TMPL_VAR NAME=type></option></TMPL_LOOP>
+</select>
+<input type="button" value=" ? " onclick="helpAllocTypes()" class="regular">
+</TMPL_IF>
+</td>
+</tr>
+
+<TMPL_IF NAME=block>
+<input type="hidden" name="block" value="<TMPL_VAR NAME=block>">
+<input type="hidden" name="fbassign" value="y">
+<TMPL_ELSE>
+<tr class="row0">
+<td>Subnet CIDR mask length:&nbsp;</td>
+<td valign=top>&nbsp;/&nbsp;<input type="text" name="maskbits" size="3" maxlength="3"></td>
+</tr>
+</TMPL_IF>
+
+<tr class="<TMPL_VAR NAME=rowa>">
+<td>Customer ID:&nbsp;</td>
+<td><input type="text" name="custid" size="15" maxlength="15"> (Only required for Customer allocations)</td>
+</tr>
+
+<tr class="<TMPL_VAR NAME=rowb>">
+<td>Wifi tower/Fibre demarc</td>
+<td>
+<select name="node">
+	<option selected>-</option>
+<TMPL_LOOP NAME=nodelist>
+	<option value="<TMPL_VAR NAME=nid>"><TMPL_VAR NAME=nname></option></TMPL_LOOP>
+</select>
+&nbsp;<a href="javascript:popNotes('/ip/newnode.html')">Add new location</a>
+</td>
+</tr>
+
+<TMPL_UNLESS NAME=block>
+<tr class="<TMPL_VAR NAME=rowa>">
+<td>Route from/through:&nbsp;</td>
+<td>
+<select name="pop">
+	<option selected value=>-</option>
+<TMPL_LOOP NAME=pops>
+	<option><TMPL_VAR NAME=pop></option></TMPL_LOOP>
+</select>
+</td>
+</tr>
+
+<tr class="<TMPL_VAR NAME=rowb>">
+<td>Route/allocate from this master:&nbsp;</td>
+<td>
+<select name=allocfrom>
+	<option selected>-</option>
+<TMPL_LOOP NAME=masterlist>
+	<option><TMPL_VAR NAME=master></option></TMPL_LOOP>
+</select>
+Allow automatic allocation from private IP ranges:<input type=checkbox name=allowpriv></td>
+</tr>
+</TMPL_UNLESS>
+
+<tr class="<TMPL_VAR NAME=rowa>">
+<td>Circuit ID:&nbsp;</td>
+<td><input name=circid size=40></td>
+</tr>
+
+<tr class="<TMPL_VAR NAME=rowb>">
+<td>Description/Name:&nbsp;</td>
+<td><input name="desc" size=40></td>
+</tr>
+
+<tr class="<TMPL_VAR NAME=rowa>">
+<td>Notes:&nbsp;</td>
+<td><textarea name="notes" rows="3" cols="40"></textarea></td>
+</tr>
+
+<TMPL_IF NAME=privdata>
+<tr class="<TMPL_VAR NAME=rowb>">
+<td>Restricted data:</td>
+<td><textarea rows="3" cols="64" name="privdata" class="regular"></textarea></td>
+</tr>
+</TMPL_IF>
+
+<tr class="<TMPL_IF NAME=privdata><TMPL_VAR NAME=rowa><TMPL_ELSE><TMPL_VAR NAME=rowb></TMPL_IF>">
+<td class="center" colspan="2"><input type="submit" value="  Assign  "></td>
+<input type="hidden" name="action" value="confirm">
+</tr>
+
+</form>
+</table>
+
+</div>
