diff --git a/include/class.category.php b/include/class.category.php
index 8e6be6b00e8b225b06e0d7ef9dc4b0bc2b5ab114..a32d0563d3cafa733ff1bd7ee1440a502517ca10 100644
--- a/include/class.category.php
+++ b/include/class.category.php
@@ -12,6 +12,7 @@
 
     vim: expandtab sw=4 ts=4 sts=4:
 **********************************************************************/
+require_once INCLUDE_DIR . 'class.faq.php';
 
 class Category extends VerySimpleModel {
 
@@ -26,6 +27,8 @@ class Category extends VerySimpleModel {
         ),
     );
 
+    var $_local;
+
     /* ------------------> Getter methods <--------------------- */
     function getId() { return $this->category_id; }
     function getName() { return $this->name; }
@@ -38,6 +41,50 @@ class Category extends VerySimpleModel {
     function isPublic() { return $this->ispublic; }
     function getHashtable() { return $this->ht; }
 
+    // Translation interface ----------------------------------
+    function getTranslateTag($subtag) {
+        return _H(sprintf('category.%s.%s', $subtag, $this->getId()));
+    }
+    function getLocal($subtag) {
+        $tag = $this->getTranslateTag($subtag);
+        $T = CustomDataTranslation::translate($tag);
+        return $T != $tag ? $T : $this->ht[$subtag];
+    }
+    function getLocalDescription($lang=false) {
+        return $this->_getLocal('description', $lang);
+    }
+    function getLocalName($lang=false) {
+        return $this->_getLocal('name', $lang);
+    }
+    function _getLocal($what, $lang=false) {
+        if (!$lang) {
+            $lang = $this->getDisplayLang();
+        }
+        $translations = $this->getAllTranslations();
+        foreach ($translations as $t) {
+            if (0 === strcasecmp($lang, $t->lang)) {
+                $data = $t->getComplex();
+                if (isset($data[$what]))
+                    return $data[$what];
+            }
+        }
+        return $this->ht[$what];
+    }
+    function getAllTranslations() {
+        if (!isset($this->_local)) {
+            $tag = $this->getTranslateTag('c:d');
+            $this->_local = CustomDataTranslation::allTranslations($tag, 'article');
+        }
+        return $this->_local;
+    }
+    function getDisplayLang() {
+        if (isset($_REQUEST['kblang']))
+            $lang = $_REQUEST['kblang'];
+        else
+            $lang = Internationalization::getCurrentLanguage();
+        return $lang;
+    }
+
     function getTopArticles() {
         return $this->faqs
             ->filter(Q::not(array('ispublished'=>0)))
@@ -77,7 +124,7 @@ class Category extends VerySimpleModel {
         if ($validation)
             return true;
 
-        $this->ispublic = !!$vars['public'];
+        $this->ispublic = $vars['ispublic'];
         $this->name = $vars['name'];
         $this->description = Format::sanitize($vars['description']);
         $this->notes = Format::sanitize($vars['notes']);
@@ -85,6 +132,9 @@ class Category extends VerySimpleModel {
         if (!$this->save())
             return false;
 
+        if (isset($vars['trans']) && !$this->saveTranslations($vars))
+            return false;
+
         // TODO: Move FAQs if requested.
 
         return true;
@@ -107,6 +157,53 @@ class Category extends VerySimpleModel {
         return parent::save($refetch || $this->dirty);
     }
 
+    function saveTranslations($vars) {
+        global $thisstaff;
+
+        foreach ($this->getAllTranslations() as $t) {
+            $trans = @$vars['trans'][$t->lang];
+            if (!$trans || !array_filter($trans))
+                // Not updating translations
+                continue;
+
+            // Content is not new and shouldn't be added below
+            unset($vars['trans'][$t->lang]);
+            $content = array('name' => $trans['name'],
+                'description' => Format::sanitize($trans['description']));
+
+            // Don't update content which wasn't updated
+            if ($content == $t->getComplex())
+                continue;
+
+            $t->text = $content;
+            $t->agent_id = $thisstaff->getId();
+            $t->updated = SqlFunction::NOW();
+            if (!$t->save())
+                return false;
+        }
+        // New translations (?)
+        $tag = $this->getTranslateTag('c:d');
+        foreach ($vars['trans'] as $lang=>$parts) {
+            $content = array('name' => @$parts['name'],
+                'description' => Format::sanitize(@$parts['description']));
+            if (!array_filter($content))
+                continue;
+            $t = CustomDataTranslation::create(array(
+                'type'      => 'article',
+                'object_hash' => $tag,
+                'lang'      => $lang,
+                'text'      => $content,
+                'revision'  => 1,
+                'agent_id'  => $thisstaff->getId(),
+                'updated'   => SqlFunction::NOW(),
+            ));
+            if (!$t->save())
+                return false;
+        }
+        return true;
+    }
+
+
     /* ------------------> Static methods <--------------------- */
 
     static function findIdByName($name) {
diff --git a/include/staff/category.inc.php b/include/staff/category.inc.php
index ff1ef1f93e558c31c96dd43e800a300519bf333f..f96fc6019d9563ed94e72706fd41042f44719c3c 100644
--- a/include/staff/category.inc.php
+++ b/include/staff/category.inc.php
@@ -10,6 +10,20 @@ if($category && $_REQUEST['a']!='add'){
     $info['id']=$category->getId();
     $info['notes'] = Format::viewableImages($category->getNotes());
     $qstr.='&id='.$category->getId();
+    $langs = $cfg->getSecondaryLanguages();
+    $translations = $category->getAllTranslations();
+    foreach ($langs as $tag) {
+        foreach ($translations as $t) {
+            if (strcasecmp($t->lang, $tag) === 0) {
+                $trans = $t->getComplex();
+                $info['trans'][$tag] = array(
+                    'name' => $trans['name'],
+                    'description' => Format::viewableImages($trans['description']),
+                );
+                break;
+            }
+        }
+    }
 }else {
     $title=__('Add New Category');
     $action='create';
@@ -25,57 +39,101 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
  <input type="hidden" name="a" value="<?php echo Format::htmlchars($_REQUEST['a']); ?>">
  <input type="hidden" name="id" value="<?php echo $info['id']; ?>">
  <h2><?php echo __('FAQ Category');?></h2>
- <table class="form_table" width="940" border="0" cellspacing="0" cellpadding="2">
-    <thead>
-        <tr>
-            <th colspan="2">
-                <h4><?php echo $title; ?></h4>
-            </th>
-        </tr>
-    </thead>
-    <tbody>
-        <tr>
-            <th colspan="2">
-                <em><?php echo __('Category information'); ?>
-                <i class="help-tip icon-question-sign" href="#category_information"></i></em>
-            </th>
-        </tr>
-        <tr>
-            <td width="180" class="required"><?php echo __('Category Type');?>:</td>
-            <td>
-                <input type="radio" name="ispublic" value="1" <?php echo $info['ispublic']?'checked="checked"':''; ?>><b><?php echo __('Public');?></b> <?php echo __('(publish)');?>
-                &nbsp;&nbsp;&nbsp;&nbsp;
-                <input type="radio" name="ispublic" value="0" <?php echo !$info['ispublic']?'checked="checked"':''; ?>><?php echo __('Private');?> <?php echo __('(internal)');?>
-                &nbsp;<span class="error">*&nbsp;<?php echo $errors['ispublic']; ?></span>
-            </td>
-        </tr>
-        <tr>
-            <td colspan=2>
-                <div style="padding-top:3px;"><b><?php echo __('Category Name');?></b>:&nbsp;<span class="faded"><?php echo __('Short descriptive name.');?></span></div>
-                    <input type="text" size="70" name="name" value="<?php echo $info['name']; ?>">
-                    &nbsp;<span class="error">*&nbsp;<?php echo $errors['name']; ?></span>
-                <br>
-                <div style="padding-top:5px;">
-                    <b><?php echo __('Category Description');?></b>:&nbsp;<span class="faded"><?php echo __('Summary of the category.');?></span>
-                    &nbsp;
-                    <font class="error">*&nbsp;<?php echo $errors['description']; ?></font></div>
-                    <textarea class="richtext" name="description" cols="21" rows="12" style="width:98%;"><?php echo $info['description']; ?></textarea>
-            </td>
-        </tr>
-        <tr>
-            <th colspan="2">
-                <em><?php echo __('Internal Notes');?>&nbsp;</em>
-            </th>
-        </tr>
-        <tr>
-            <td colspan=2>
-                <textarea class="richtext no-bar" name="notes" cols="21"
-                    rows="8" style="width: 80%;"><?php echo $info['notes']; ?></textarea>
-            </td>
-        </tr>
-    </tbody>
-</table>
-<p style="padding-left:225px;">
+ <div class="faq-title" style="margin:5px 0 15px">
+    <?php echo $title; ?>
+ </div>
+
+    <div style="margin:8px 0"><strong><?php echo __('Category Type');?>:</strong>
+        <span class="error">*</span></div>
+    <div style="margin-left:5px">
+    <input type="radio" name="ispublic" value="2" <?php echo $info['ispublic']?'checked="checked"':''; ?>><b><?php echo __('Featured');?></b> <?php echo __('(on front-page sidebar)');?>
+    <br/>
+    <input type="radio" name="ispublic" value="1" <?php echo $info['ispublic']?'checked="checked"':''; ?>><b><?php echo __('Public');?></b> <?php echo __('(publish)');?>
+    <br/>
+    <input type="radio" name="ispublic" value="0" <?php echo !$info['ispublic']?'checked="checked"':''; ?>><?php echo __('Private');?> <?php echo __('(internal)');?>
+    <br/>
+    <div class="error"><?php echo $errors['ispublic']; ?></div>
+    </div>
+
+<div style="margin-top:20px"></div>
+
+<ul class="tabs" style="margin-top:9px;">
+    <li class="active"><a href="#info"><?php echo __('Category Information'); ?></a></li>
+    <li><a href="#notes"><?php echo __('Internal Notes'); ?></a></li>
+</ul>
+
+<div class="tab_content" id="info">
+<?php
+$langs = Internationalization::getConfiguredSystemLanguages();
+if (count($langs) > 1) { ?>
+    <ul class="vertical tabs left" style="margin-top:10px;">
+        <li class="empty"><i class="icon-globe" title="This content is translatable"></i></li>
+<?php foreach ($langs as $tag=>$i) {
+    list($lang, $locale) = explode('_', $tag);
+ ?>
+    <li class="<?php if ($tag == $cfg->getPrimaryLanguage()) echo "active";
+        ?>"><a href="#lang-<?php echo $tag; ?>" title="<?php
+        echo Internationalization::getLanguageDescription($tag);
+    ?>"><span class="flag flag-<?php echo strtolower($i['flag'] ?: $locale ?: $lang); ?>"></span>
+    </a></li>
+<?php } ?>
+    </ul>
+<?php
+} ?>
+
+
+
+<?php foreach ($langs as $tag=>$i) {
+    $code = $i['code'];
+    $cname = 'name';
+    $dname = 'description';
+    if ($tag == $cfg->getPrimaryLanguage()) {
+        $category = $info[$cname];
+        $desc = $info[$dname];
+    }
+    else {
+        $category = $info['trans'][$code][$cname];
+        $desc = $info['trans'][$code][$dname];
+        $cname = "trans[$code][$cname]";
+        $dname = "trans[$code][$dname]";
+    } ?>
+    <div class="tab_content" style="margin:0 45px" style="<?php
+        if ($code != $cfg->getPrimaryLanguage()) echo "display:none;";
+      ?>" id="lang-<?php echo $tag; ?>"
+      <?php if ($i['direction'] == 'rtl') echo 'dir="rtl" class="rtl"'; ?>
+    >
+    <div style="padding:8px 0;">
+        <b><?php echo __('Category Name');?></b>:
+        <span class="error">*</span>
+        <div class="faded"><?php echo __('Short descriptive name.');?></div>
+    </div>
+    <input type="text" size="70" style="font-size:110%;width:100%;box-sizing:border-box"
+        name="<?php echo $cname; ?>" value="<?php echo $category; ?>">
+    <div class="error"><?php echo $errors['name']; ?></div>
+
+    <div style="padding:8px 0;">
+        <b><?php echo __('Category Description');?></b>:
+        <span class="error">*</span>
+        <div class="faded"><?php echo __('Summary of the category.');?></div>
+        <div class="error"><?php echo $errors['description']; ?></div>
+    </div>
+    <textarea class="richtext" name="<?php echo $dname; ?>" cols="21" rows="12"
+        style="width:100%;"><?php
+        echo $desc; ?></textarea>
+    </div>
+<?php } ?>
+</div>
+
+
+<div class="tab_content" id="notes" style="display:none;">
+    <b><?php echo __('Internal Notes');?></b>:
+    <div class="faded"><?php echo __("Be liberal, they're internal");?></div>
+    <textarea class="richtext no-bar" name="notes" cols="21"
+        rows="8" style="width: 80%;"><?php echo $info['notes']; ?></textarea>
+</div>
+
+
+<p style="text-align:center">
     <input type="submit" name="submit" value="<?php echo $submit_text; ?>">
     <input type="reset"  name="reset"  value="<?php echo __('Reset');?>">
     <input type="button" name="cancel" value="<?php echo __('Cancel');?>" onclick='window.location.href="categories.php"'>