diff --git a/include/class.format.php b/include/class.format.php
index 10859d15a1885a2775c1c296b1a52b017269fc7a..c3abb002992695c54323a946f973c9ed456a7042 100644
--- a/include/class.format.php
+++ b/include/class.format.php
@@ -53,7 +53,7 @@ class Format {
             $text = mb_convert_encoding($text, $encoding, $charset);
         elseif(!strcasecmp($encoding, 'utf-8')) //forced blind utf8 encoding.
             $text = function_exists('imap_utf8')?imap_utf8($text):utf8_encode($text);
-        
+
         // If $text is false, then we have a (likely) invalid charset, use
         // the original text and assume 8-bit (latin-1 / iso-8859-1)
         // encoding
@@ -298,5 +298,20 @@ class Format {
         return date($format, ($gmtimestamp+ ($offset*3600)));
     }
 
+    // Thanks, http://stackoverflow.com/a/2955878/1025836
+    /* static */
+    function slugify($text) {
+        // replace non letter or digits by -
+        $text = preg_replace('~[^\p{L}\p{N}]+~u', '-', $text);
+
+        // trim
+        $text = trim($text, '-');
+
+        // lowercase
+        $text = strtolower($text);
+
+        return (empty($text)) ? 'n-a' : $text;
+    }
+
 }
 ?>
diff --git a/include/staff/page.inc.php b/include/staff/page.inc.php
index be52b3607bda6e269d5f85bc7f8efc49f423b0bc..35881ee742046387c9dea3630fc771546232822b 100644
--- a/include/staff/page.inc.php
+++ b/include/staff/page.inc.php
@@ -13,6 +13,7 @@ if($page && $_REQUEST['a']!='add'){
     $action='update';
     $submit_text='Save Changes';
     $info=$page->getHashtable();
+    $slug = Format::slugify($info['name']);
     $qstr.='&id='.$page->getId();
 }else {
     $title='Add New Page';
@@ -64,6 +65,17 @@ $info=Format::htmlchars(($errors && $_POST)?$_POST:$info);
                 &nbsp;<span class="error">*&nbsp;<?php echo $errors['type']; ?></span>
             </td>
         </tr>
+        <?php if ($info['name'] && $info['type'] == 'other') { ?>
+        <tr>
+            <td width="180" class="required">
+                Public URL:
+            </td>
+            <td><a href="<?php echo sprintf("%s/pages/%s",
+                    $ost->getConfig()->getBaseUrl(), urlencode($slug));
+                ?>">pages/<?php echo $slug; ?></a>
+            </td>
+        </tr>
+        <?php } ?>
         <tr>
             <td width="180" class="required">
                 Status:
diff --git a/include/staff/pages.inc.php b/include/staff/pages.inc.php
index 8fc14be6239ff685c0bb57630fe17fc313e7951c..cb5fd243af2ada6e39e53b2b9a274705dd831ed5 100644
--- a/include/staff/pages.inc.php
+++ b/include/staff/pages.inc.php
@@ -2,7 +2,8 @@
 if(!defined('OSTADMININC') || !$thisstaff->isAdmin()) die('Access Denied');
 
 $qstr='';
-$sql='SELECT page.id, page.isactive, page.name, page.created, page.updated, count(topic.topic_id) as topics '
+$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 ';
diff --git a/pages/.htaccess b/pages/.htaccess
new file mode 100644
index 0000000000000000000000000000000000000000..ff79be5c961ac099b5d0dd6cb2c73d9cb1fdc77c
--- /dev/null
+++ b/pages/.htaccess
@@ -0,0 +1,11 @@
+<IfModule mod_rewrite.c>
+
+RewriteEngine On
+
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteCond %{REQUEST_FILENAME} !-d
+RewriteCond %{REQUEST_URI} (.*/pages)
+
+RewriteRule ^(.*)$ %1/index.php/$1 [L]
+
+</IfModule>
diff --git a/pages/index.php b/pages/index.php
new file mode 100644
index 0000000000000000000000000000000000000000..78c49e73783c608b041f833745f14ba78ad5a2dc
--- /dev/null
+++ b/pages/index.php
@@ -0,0 +1,55 @@
+<?php
+/*********************************************************************
+    pages/index.php
+
+    Custom pages servlet
+
+    Peter Rotich <peter@osticket.com>
+    Jared Hancock <jared@osticket.com>
+    Copyright (c)  2006-2013 osTicket
+    http://www.osticket.com
+
+    Released under the GNU General Public License WITHOUT ANY WARRANTY.
+    See LICENSE.TXT for details.
+
+    vim: expandtab sw=4 ts=4 sts=4:
+**********************************************************************/
+@chdir(realpath(dirname(__file__).'/../'));
+define('ROOT_PATH','../');
+
+require_once('client.inc.php');
+require_once(INCLUDE_DIR.'class.format.php');
+require_once(INCLUDE_DIR.'class.page.php');
+
+// Determine the requested page
+// - Strip extension
+$slug = Format::slugify($ost->get_path_info());
+
+// Get the part before the first dash
+$first_word = explode('-', $slug);
+$first_word = $first_word[0];
+
+$sql = 'SELECT id, name FROM '.PAGE_TABLE
+    .' WHERE name LIKE '.db_input("$first_word%");
+$page_id = null;
+
+$res = db_query($sql);
+while (list($id, $name) = db_fetch_row($res)) {
+    if (Format::slugify($name) == $slug) {
+        $page_id = $id;
+        break;
+    }
+}
+
+if (!$page_id || !($page = Page::lookup($page_id)))
+    Http::response(404, 'Page Not Found');
+
+if (!$page->isActive() || $page->getType() != 'other')
+    Http::response(404, 'Page Not Found');
+
+require(CLIENTINC_DIR.'header.inc.php');
+
+print $page->getBody();
+
+require(CLIENTINC_DIR.'footer.inc.php');
+?>