Index: templates/ticket.cs
===================================================================
--- templates/ticket.cs	(revision 4524)
+++ templates/ticket.cs	(working copy)
@@ -65,7 +65,7 @@
     if:fullrow && idx % 2 ?><th></th><td></td></tr><tr><?cs /if ?>
     <th id="h_<?cs var:name(field) ?>"><?cs var:field.label ?>:</th>
     <td<?cs if:fullrow ?> colspan="3"<?cs /if ?> headers="h_<?cs
-      var:name(field) ?>"><?cs var:ticket[name(field)] ?></td><?cs 
+      var:name(field) ?>"><?cs var:field.formatted ?></td><?cs 
     if:idx % 2 || fullrow ?></tr><tr><?cs 
     elif:idx == num_fields - 1 ?><th></th><td></td><?cs
     /if ?><?cs set:idx = idx + #fullrow + 1 ?><?cs
@@ -135,12 +135,20 @@
    each:field = change.fields ?>
     <li><strong><?cs var:name(field) ?></strong> <?cs
     if:name(field) == 'attachment' ?><em><?cs var:field.new ?></em> added<?cs
+    elif:field.format != 'plain' ?>changed<?cs
     elif:field.old && field.new ?>changed from <em><?cs
      var:field.old ?></em> to <em><?cs var:field.new ?></em><?cs
     elif:!field.old && field.new ?>set to <em><?cs var:field.new ?></em><?cs
     elif:field.old && !field.new ?>deleted<?cs
     else ?>changed<?cs
-    /if ?>.</li>
+    /if ?>.<?cs
+    if field.format != 'plain' ?><div style="font-size:0.8em;font-weight:bold;">Detail <span style="cursor:pointer" onclick="document.getElementById('chang_detail_<?cs var:change.cnum ?>_<?cs var:name(field) ?>').style.display='block';">+</span>/<span style="cursor:pointer" onclick="document.getElementById('chang_detail_<?cs var:change.cnum ?>_<?cs var:name(field) ?>').style.display='none';">-</span></div>
+      <div id="chang_detail_<?cs var:change.cnum ?>_<?cs var:name(field) ?>" style="display:none;">
+        <div style="border: 1px outset #996; padding: 1em;"><?cs var:field.old ?></div>
+        <div style="margin:1em;2em;">to</div>
+        <div style="border: 1px outset #996; padding: 1em;"><?cs var:field.new ?></div>
+      </div><?cs
+    /if ?></li>
     <?cs
    /each ?>
    </ul><?cs
Index: ticket/api.py
===================================================================
--- ticket/api.py	(revision 4524)
+++ ticket/api.py	(working copy)
@@ -164,7 +164,8 @@
                 'type': config.get(name),
                 'order': config.getint(name + '.order', 0),
                 'label': config.get(name + '.label') or name.capitalize(),
-                'value': config.get(name + '.value', '')
+                'value': config.get(name + '.value', ''),
+                'format': config.get(name + '.format', 'plain') 
             }
             if field['type'] == 'select' or field['type'] == 'radio':
                 field['options'] = config.getlist(name + '.options', sep='|')
@@ -176,6 +177,15 @@
 
         fields.sort(lambda x, y: cmp(x['order'], y['order']))
         return fields
+    
+    def get_field_by_name(self, name):
+        ret = None
+        for f in self.get_ticket_fields():
+            if f['name'] == name:
+                ret = f
+                break
+        return ret
+        
 
     # IPermissionRequestor methods
 
Index: ticket/web_ui.py
===================================================================
--- ticket/web_ui.py	(revision 4524)
+++ ticket/web_ui.py	(working copy)
@@ -583,6 +583,18 @@
             if name in ('summary', 'reporter', 'description', 'type', 'status',
                         'resolution', 'owner'):
                 field['skip'] = True
+            else: 
+                if 'format' in field: 
+                    if field['format'] == 'wiki': 
+                        field['formatted'] = wiki_to_html(ticket.values.get(name), self.env, req, db) 
+                    elif field['format'] == 'wiki_oneliner': 
+                        field['formatted'] = wiki_to_oneliner(ticket.values.get(name), self.env, db, shorten=True) 
+                    elif field['format'] == 'pre': 
+                        field['formatted'] = wiki_to_html('{{{\n' + ticket.values.get(name) + '\n}}}', self.env, req, db) 
+                    else: 
+                        field['formatted'] = ticket.values.get(name) 
+                else: 
+                    field['formatted'] = ticket.values.get(name) 
             req.hdf['ticket.fields.' + name] = field
 
         req.hdf['ticket.reporter_id'] = reporter_id
@@ -660,6 +672,7 @@
         in a `dict` object.
         """
         changelog = ticket.get_changelog(when=when, db=db)
+        custom_fields = [f['name'] for f in ticket.fields if f.get('custom')]
         autonum = 0 # used for "root" numbers
         last_uid = current = None
         for date, author, field, old, new, permanent in changelog:
@@ -689,6 +702,23 @@
                         this_num = old
                     current['cnum'] = int(this_num)
             else:
-                current['fields'][field] = {'old': old, 'new': new}
+                type = 'standard'
+                format = 'plain'
+                if field in custom_fields:
+                    type = 'custom'
+                    field_def = TicketSystem(self.env).get_field_by_name(field)
+                    if field_def and 'format' in field_def:
+                        format = field_def['format']
+                        if format == 'wiki':
+                            old = wiki_to_html(old, self.env, None, db)
+                            new = wiki_to_html(new, self.env, None, db)
+                        elif format == 'wiki_oneliner':
+                            old = wiki_to_oneliner(old, self.env, db, shorten=True)
+                            new = wiki_to_oneliner(new, self.env, db, shorten=True)
+                        elif format == 'pre':
+                            old = wiki_to_html('{{{\n' + old + '\n}}}', self.env, None, db)
+                            new = wiki_to_html('{{{\n' + new + '\n}}}', self.env, None, db)
+                
+                current['fields'][field] = {'old': old, 'new': new, 'type': type, 'format': format}
         if current:
             yield current

