diff --git a/bootstrap.php b/bootstrap.php
index c3a02a92f41681f1c489443aaa39b4a23a2d8833..832fe96e50a6b89f9c7d952c5fa355295fcd8ca5 100644
--- a/bootstrap.php
+++ b/bootstrap.php
@@ -63,7 +63,7 @@ class Bootstrap {
         define('CONFIG_TABLE',$prefix.'config');
 
         define('CANNED_TABLE',$prefix.'canned_response');
-        define('PAGE_TABLE', $prefix.'page');
+        define('PAGE_TABLE', $prefix.'content');
         define('FILE_TABLE',$prefix.'file');
         define('FILE_CHUNK_TABLE',$prefix.'file_chunk');
 
diff --git a/include/ajax.content.php b/include/ajax.content.php
index acc238c34e828c414d3be133c836bb82d3f311b7..02b3bd55061364170c7c323f2988aeeeb8f90f27 100644
--- a/include/ajax.content.php
+++ b/include/ajax.content.php
@@ -125,5 +125,44 @@ class ContentAjaxAPI extends AjaxController {
             break;
         }
     }
+
+    function manageContent($id, $lang=false) {
+        global $thisstaff;
+
+        if (!$thisstaff)
+            Http::response(403, 'Login Required');
+
+        $content = Page::lookup($id, $lang);
+        include STAFFINC_DIR . 'templates/content-manage.tmpl';
+    }
+
+    function manageNamedContent($type, $lang=false) {
+        global $thisstaff;
+
+        if (!$thisstaff)
+            Http::response(403, 'Login Required');
+
+        $content = Page::lookup(Page::getIdByType($type, $lang));
+        include STAFFINC_DIR . 'templates/content-manage.tmpl.php';
+    }
+
+    function updateContent($id) {
+        global $thisstaff;
+
+        if (!$thisstaff)
+            Http::response(403, 'Login Required');
+        elseif (!$_POST['name'] || !$_POST['body'])
+            Http::response(422, 'Please submit name and body');
+        elseif (!($content = Page::lookup($id)))
+            Http::response(404, 'No such content');
+
+        $vars = array_merge($content->getHashtable(), $_POST);
+        if (!$content->save($id, $vars, $errors)) {
+            if ($errors['err'])
+                Http::response(422, $errors['err']);
+            else
+                Http::response(500, 'Unable to update content: '.print_r($errors, true));
+        }
+    }
 }
 ?>
diff --git a/include/class.page.php b/include/class.page.php
index f0ada9a6c077dfa1099a55d64867a82cb294c501..553e342a7e2f657aa6d2df307479b65f7dffa764 100644
--- a/include/class.page.php
+++ b/include/class.page.php
@@ -19,13 +19,13 @@ class Page {
     var $ht;
     var $attachments;
 
-    function Page($id) {
+    function Page($id, $lang=false) {
         $this->id=0;
         $this->ht = array();
-        $this->load($id);
+        $this->load($id, $lang);
     }
 
-    function load($id=0) {
+    function load($id=0, $lang=false) {
 
         if(!$id && !($id=$this->getId()))
             return false;
@@ -33,7 +33,8 @@ class Page {
         $sql='SELECT page.*, count(topic.page_id) as topics '
             .' FROM '.PAGE_TABLE.' page '
             .' LEFT JOIN '.TOPIC_TABLE. ' topic ON(topic.page_id=page.id) '
-            .' WHERE page.id='.db_input($id)
+            . ' WHERE page.content_id='.db_input($id)
+            . ($lang ? ' AND lang='.db_input($lang) : '')
             .' GROUP By page.id';
 
         if (!($res=db_query($sql)) || !db_num_rows($res))
@@ -195,10 +196,25 @@ class Page {
         return self::getActivePages(array('type' => 'thank-you'));
     }
 
-    function getIdByName($name) {
+    function getIdByName($name, $lang=false) {
 
         $id = 0;
         $sql = ' SELECT id FROM '.PAGE_TABLE.' WHERE name='.db_input($name);
+        if ($lang)
+            $sql .= ' AND lang='.db_input($lang);
+
+        if(($res=db_query($sql)) && db_num_rows($res))
+            list($id) = db_fetch_row($res);
+
+        return $id;
+    }
+
+    function getIdByType($type, $lang=false) {
+        $id = 0;
+        $sql = ' SELECT id FROM '.PAGE_TABLE.' WHERE `type`='.db_input($type);
+        if ($lang)
+            $sql .= ' AND lang='.db_input($lang);
+
         if(($res=db_query($sql)) && db_num_rows($res))
             list($id) = db_fetch_row($res);
 
@@ -224,8 +240,6 @@ class Page {
 
         if(!$vars['type'])
             $errors['type'] = 'Type required';
-        elseif(!in_array($vars['type'], array('landing', 'offline', 'thank-you', 'other')))
-            $errors['type'] = 'Invalid selection';
 
         if(!$vars['name'])
             $errors['name'] = 'Name required';
@@ -254,10 +268,13 @@ class Page {
 
         } else {
             $sql='INSERT INTO '.PAGE_TABLE.' SET '.$sql.', created=NOW()';
-            if(db_query($sql) && ($id=db_insert_id()))
-                return $id;
+            if (!db_query($sql) || !($id=db_insert_id())) {
+                $errors['err']='Unable to create page. Internal error';
+                return false;
+            }
 
-            $errors['err']='Unable to create page. Internal error';
+            // TODO: Update `content_id`
+            return $id;
         }
 
         return false;
diff --git a/include/staff/pages.inc.php b/include/staff/pages.inc.php
index 34a3fa2f9d2ca062b285400e398a2ffc756598a4..5dff4eced87e1d141ff292cff029cd46b6a94119 100644
--- a/include/staff/pages.inc.php
+++ b/include/staff/pages.inc.php
@@ -6,7 +6,7 @@ $sql='SELECT page.id, page.isactive, page.name, page.created, page.updated, '
      .'page.type, count(topic.topic_id) as topics '
      .' FROM '.PAGE_TABLE.' page '
      .' LEFT JOIN '.TOPIC_TABLE.' topic ON(topic.page_id=page.id) '
-     .' WHERE 1 ';
+     .' WHERE type in ("other","landing","thank-you","offline") ';
 $sortOptions=array(
         'name'=>'page.name', 'status'=>'page.isactive',
         'created'=>'page.created', 'updated'=>'page.updated',
diff --git a/include/staff/settings-access.inc.php b/include/staff/settings-access.inc.php
index cb6306f250b1b1a00ca99156ef2afcca84bb6071..4d27d8ed2874a805140a23232a8c1f804c3161d9 100644
--- a/include/staff/settings-access.inc.php
+++ b/include/staff/settings-access.inc.php
@@ -131,6 +131,17 @@ if(!defined('OSTADMININC') || !$thisstaff || !$thisstaff->isAdmin() || !$config)
                  Maximum idle time in minutes before a client must log in again (enter 0 to disable).
             </td>
         </tr>
+        <tr>
+            <th colspan="2">
+                <em><b>Authentication and Registration Templates</b></em>
+            </th>
+        </tr>
+        <tr>
+            <td>New Registration Email</td>
+            <td><a href="ajax.php/content/new-registration/manage"
+                onclick="javascript:
+                    $.dialog($(this).attr('href'), 200);
+                    return false;">Manage</a></td>
 </tbody>
 </table>
 <p style="text-align:center">
diff --git a/scp/ajax.php b/scp/ajax.php
index 5bc266064fda0a468c766d093371efffa411d3c5..9ef736ef7999896da99e8c889e97dde6a7b682d2 100644
--- a/scp/ajax.php
+++ b/scp/ajax.php
@@ -42,7 +42,10 @@ $dispatcher = patterns('',
     url('^/content/', patterns('ajax.content.php:ContentAjaxAPI',
         url_get('^log/(?P<id>\d+)', 'log'),
         url_get('^ticket_variables', 'ticket_variables'),
-        url_get('^signature/(?P<type>\w+)(?:/(?P<id>\d+))?$', 'getSignature')
+        url_get('^signature/(?P<type>\w+)(?:/(?P<id>\d+))?$', 'getSignature'),
+        url_get('^(?P<id>\d+)/(?:(?P<lang>\w+)/)?manage$', 'manageContent'),
+        url_get('^(?P<id>[\w-]+)/(?:(?P<lang>\w+)/)?manage$', 'manageNamedContent'),
+        url_post('^(?P<id>\d+)(?:/(?P<lang>\w+))?$', 'updateContent')
     )),
     url('^/config/', patterns('ajax.config.php:ConfigAjaxAPI',
         url_get('^scp', 'scp')