How do I use a hidden column in a custom search template?
OK. I figured it out eventually. This is how I got it to work. It seems a little wonky but it functions


Add the column to the list of columns 
Override the template
Alter the rows to add the link
AND unset the column in Alter rows


The constructor columns must contain

  ts('Org id') =&gt; 'org_id',


The override

  public function templateFile() {
    return "CRM/Contact/Form/Search/Custom/mySearch.tpl";
  }


The template

Add snippets in each of the column headers section and the rows section skipping an item in the loop. Eg. {if $header.sort neq 'org_id'}

For the headers:

 {foreach from=$columnHeaders item=header}
    {if $header.sort neq 'org_id'}
      &lt;th scope="col"&gt;
      {if $header.sort}
        {assign var='key' value=$header.sort}
        {$sort-&gt;_response.$key.link}
      {else}
          {$header.name}
      {/if}
     &lt;/th&gt;
   {/if}
{/foreach}


For the rows:

{foreach from=$columnHeaders item=header}
   {assign var=fName value=$header.sort}
   {if $header.sort neq 'org_id'}
     {if $fName eq 'sort_name'}
       &lt;td&gt;&lt;a href="{crmURL p='civicrm/contact/view' q="reset=1&amp;cid=`$row.contact_id`&amp;key=`$qfKey`&amp;context=custom"}"&gt;{$row.sort_name}&lt;/a&gt;&lt;/td&gt;
      {else}
        &lt;td&gt;{$row.$fName}&lt;/td&gt;
      {/if}
   {/if}
{/foreach}


The alter rows

Note the added unset line.

function alterRow( &amp;$row ) {
  $url = CRM_Utils_System::url('civicrm/contact/view', "reset=1&amp;cid={$row['org_id']}");
  $row['organization_name'] = "&lt;a href=\"{$url}\"&gt;{$row['organization_name']}&lt;/a&gt;";
  unset($row['org_id']);
}