diff --git a/src/applications/directory/controller/main/PhabricatorDirectoryMainController.php b/src/applications/directory/controller/main/PhabricatorDirectoryMainController.php
index 2b65d6da7..dd178ed48 100644
--- a/src/applications/directory/controller/main/PhabricatorDirectoryMainController.php
+++ b/src/applications/directory/controller/main/PhabricatorDirectoryMainController.php
@@ -1,521 +1,521 @@
 <?php
 
 /*
  * Copyright 2012 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * You may obtain a copy of the License at
  *
  *   http://www.apache.org/licenses/LICENSE-2.0
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
 
 class PhabricatorDirectoryMainController
   extends PhabricatorDirectoryController {
 
   private $filter;
 
   public function willProcessRequest(array $data) {
     $this->filter = idx($data, 'filter');
   }
 
   public function shouldRequireAdmin() {
     // These controllers are admin-only by default, but this one is public,
     // so allow non-admin users to view it.
     return false;
   }
 
   public function processRequest() {
     $user = $this->getRequest()->getUser();
 
     $nav = $this->buildNav();
     $this->filter = $nav->selectFilter($this->filter, 'home');
 
     switch ($this->filter) {
       case 'jump':
         break;
       case 'home':
       case 'feed':
         $project_query = new PhabricatorProjectQuery();
         $project_query->setMembers(array($user->getPHID()));
         $projects = $project_query->execute();
         break;
       default:
         throw new Exception("Unknown filter '{$this->filter}'!");
     }
 
     switch ($this->filter) {
       case 'feed':
         return $this->buildFeedResponse($nav, $projects);
       case 'jump':
         return $this->buildJumpResponse($nav);
       default:
         return $this->buildMainResponse($nav, $projects);
     }
 
   }
 
   private function buildMainResponse($nav, $projects) {
     $unbreak_panel = $this->buildUnbreakNowPanel();
     $triage_panel = $this->buildNeedsTriagePanel($projects);
     $jump_panel = $this->buildJumpPanel();
     $revision_panel = $this->buildRevisionPanel();
     $tasks_panel = $this->buildTasksPanel();
     $feed_view = $this->buildFeedView($projects, $is_full = false);
 
 
     $content = array(
       $unbreak_panel,
       $triage_panel,
       $jump_panel,
       $revision_panel,
       $tasks_panel,
       $feed_view,
     );
 
     $nav->appendChild($content);
 
     return $this->buildStandardPageResponse(
       $nav,
       array(
         'title' => 'Phabricator',
       ));
   }
 
   private function buildJumpResponse($nav) {
     $request = $this->getRequest();
 
     if ($request->isFormPost()) {
       $jump = $request->getStr('jump');
       $jump = trim($jump);
 
       $help_href = PhabricatorEnv::getDocLink(
-        'articles/Jump_Nav_User_Guide.html');
+        'article/Jump_Nav_User_Guide.html');
 
       $patterns = array(
         '/^help/i'                  => 'uri:'.$help_href,
         '/^d$/i'                    => 'uri:/differential/',
         '/^r$/i'                    => 'uri:/diffusion/',
         '/^t$/i'                    => 'uri:/maniphest/',
         '/r([A-Z]+)$/'              => 'repository',
         '/r([A-Z]+)(\S+)$/'         => 'commit',
         '/^d(\d+)$/i'               => 'revision',
         '/^t(\d+)$/i'               => 'task',
 
         // TODO: '/^p$/i'                    => 'uri:/projects/',
         // TODO: '/^u$/i'                    => 'uri:/people/',
         // TODO: '/^p\s+(\S+)$/i'            => 'project',
         // TODO: '/^u\s+(\S+)$/i'            => 'user',
         // TODO: '/^task:\s+(\S+)/i'         => 'create-task',
         // TODO: '/^(?:s|symbol)\s+(\S+)/i'  => 'find-symbol',
       );
 
 
       foreach ($patterns as $pattern => $effect) {
         $matches = null;
         if (preg_match($pattern, $jump, $matches)) {
           if (!strncmp($effect, 'uri:', 4)) {
             return id(new AphrontRedirectResponse())
               ->setURI(substr($effect, 4));
           } else {
             switch ($effect) {
               case 'repository':
                 return id(new AphrontRedirectResponse())
                   ->setURI('/diffusion/'.$matches[1].'/');
               case 'commit':
                 return id(new AphrontRedirectResponse())
                   ->setURI('/'.$matches[0]);
               case 'revision':
                 return id(new AphrontRedirectResponse())
                   ->setURI('/D'.$matches[1]);
               case 'task':
                 return id(new AphrontRedirectResponse())
                   ->setURI('/T'.$matches[1]);
               default:
                 throw new Exception("Unknown jump effect '{$effect}'!");
             }
           }
         }
       }
 
       $query = new PhabricatorSearchQuery();
       $query->setQuery($jump);
       $query->save();
 
       return id(new AphrontRedirectResponse())
         ->setURI('/search/'.$query->getQueryKey().'/');
     }
 
 
     $nav->appendChild($this->buildJumpPanel());
     return $this->buildStandardPageResponse(
       $nav,
       array(
         'title' => 'Jump Nav',
       ));
   }
 
   private function buildFeedResponse($nav, $projects) {
     $view = $this->buildFeedView($projects, $is_full = true);
     $nav->appendChild($view);
     return $this->buildStandardPageResponse(
       $nav,
       array(
         'title' => 'Feed',
       ));
   }
 
   private function buildUnbreakNowPanel() {
     $user = $this->getRequest()->getUser();
     $user_phid = $user->getPHID();
 
     $task_query = new ManiphestTaskQuery();
     $task_query->withStatus(ManiphestTaskQuery::STATUS_OPEN);
     $task_query->withPriority(ManiphestTaskPriority::PRIORITY_UNBREAK_NOW);
     $task_query->setLimit(10);
     $task_query->setCalculateRows(true);
 
     $tasks = $task_query->execute();
 
     if ($tasks) {
       $panel = new AphrontPanelView();
       $panel->setHeader('Unbreak Now!');
       $panel->setCaption('Open tasks with "Unbreak Now!" priority.');
       $panel->addButton(
         phutil_render_tag(
           'a',
           array(
             'href' => '/maniphest/view/all/',
             'class' => 'grey button',
           ),
           'View All Unbreak Now ('.$task_query->getRowCount().") \xC2\xBB"));
 
       $panel->appendChild($this->buildTaskListView($tasks));
     } else {
       $panel = new AphrontMiniPanelView();
       $panel->appendChild(
         '<p><strong>No "Unbreak Now!" Tasks:</strong> '.
         'Nothing appears to be critically broken right now.</p>');
       $panel = '<br />'.$panel->render();
     }
 
     return $panel;
   }
 
   private function buildNeedsTriagePanel(array $projects) {
     $user = $this->getRequest()->getUser();
     $user_phid = $user->getPHID();
 
     if ($projects) {
       $task_query = new ManiphestTaskQuery();
       $task_query->withStatus(ManiphestTaskQuery::STATUS_OPEN);
       $task_query->withPriority(ManiphestTaskPriority::PRIORITY_TRIAGE);
       $task_query->withProjects(mpull($projects, 'getPHID'));
       $task_query->withAnyProject(true);
       $task_query->setCalculateRows(true);
       $task_query->setLimit(10);
       $tasks = $task_query->execute();
     } else {
       $tasks = array();
     }
 
     if ($tasks) {
       $panel = new AphrontPanelView();
       $panel->setHeader('Needs Triage');
       $panel->setCaption(
         'Open tasks with "Needs Triage" priority in '.
         '<a href="/project/">projects you are a member of</a>.');
 
       $panel->addButton(
         phutil_render_tag(
           'a',
           array(
             // TODO: This should filter to just your projects' need-triage
             // tasks?
             'href' => '/maniphest/view/alltriage/',
             'class' => 'grey button',
           ),
           'View All Triage ('.$task_query->getRowCount().") \xC2\xBB"));
       $panel->appendChild($this->buildTaskListView($tasks));
     } else {
       $panel = new AphrontMiniPanelView();
       $panel->appendChild(
         '<p><strong>No "Needs Triage" Tasks:</strong> '.
         'No tasks in <a href="/project/">projects you are a member of</a> '.
         'need triage.</p>');
     }
 
     return $panel;
   }
 
   private function buildRevisionPanel() {
     $user = $this->getRequest()->getUser();
     $user_phid = $user->getPHID();
 
     $revision_query = new DifferentialRevisionQuery();
     $revision_query->withStatus(DifferentialRevisionQuery::STATUS_OPEN);
     $revision_query->withResponsibleUsers(array($user_phid));
     $revision_query->needRelationships(true);
 
     // NOTE: We need to unlimit this query to hit the responsible user
     // fast-path.
     $revision_query->setLimit(null);
     $revisions = $revision_query->execute();
 
     list($active, $waiting) = DifferentialRevisionQuery::splitResponsible(
       $revisions,
       $user_phid);
 
     $panel = new AphrontPanelView();
     $panel->setHeader('Revisions Waiting on You');
     $panel->setCaption('Revisions waiting for you for review or commit.');
 
     $panel->addButton(
       phutil_render_tag(
         'a',
         array(
           'href' => '/differential/',
           'class' => 'button grey',
         ),
         "View Active Revisions \xC2\xBB"));
 
     if ($active) {
       $revision_view = id(new DifferentialRevisionListView())
         ->setRevisions($active)
         ->setUser($user);
       $phids = array_merge(
         array($user_phid),
         $revision_view->getRequiredHandlePHIDs());
       $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
 
       $revision_view->setHandles($handles);
 
       $panel->appendChild($revision_view);
     } else {
       $panel->appendChild('<p>No revisions are waiting on you.</p>');
     }
 
     return $panel;
   }
 
   private function buildTasksPanel() {
     $user = $this->getRequest()->getUser();
     $user_phid = $user->getPHID();
 
     $task_query = new ManiphestTaskQuery();
     $task_query->withStatus(ManiphestTaskQuery::STATUS_OPEN);
     $task_query->setGroupBy(ManiphestTaskQuery::GROUP_PRIORITY);
     $task_query->withOwners(array($user_phid));
     $task_query->setCalculateRows(true);
     $task_query->setLimit(10);
 
     $tasks = $task_query->execute();
 
     $panel = new AphrontPanelView();
     $panel->setHeader('Assigned Tasks');
     $panel->setCaption('Tasks assigned to you.');
 
     if ($tasks) {
       $panel->addButton(
         phutil_render_tag(
           'a',
           array(
             'href' => '/maniphest/',
             'class' => 'button grey',
           ),
           "View All Assigned Tasks (".$task_query->getRowCount().") \xC2\xBB"));
       $panel->appendChild($this->buildTaskListView($tasks));
     } else {
       $panel->addButton(
         phutil_render_tag(
           'a',
           array(
             'href' => '/maniphest/?users='.
               ManiphestTaskOwner::OWNER_UP_FOR_GRABS,
             'class' => 'button grey',
           ),
           "View Unassigned Tasks \xC2\xBB"));
       $panel->appendChild('<p>You have no assigned tasks.</p>');
     }
 
     return $panel;
   }
 
 
   private function buildTaskListView(array $tasks) {
     $user = $this->getRequest()->getUser();
 
     $phids = array_filter(mpull($tasks, 'getOwnerPHID'));
     $handles = id(new PhabricatorObjectHandleData($phids))->loadHandles();
 
     $view = new ManiphestTaskListView();
     $view->setTasks($tasks);
     $view->setUser($user);
     $view->setHandles($handles);
 
     return $view;
   }
 
   private function buildFeedView(array $projects, $is_full) {
     $request = $this->getRequest();
     $user = $request->getUser();
     $user_phid = $user->getPHID();
 
     $feed_query = new PhabricatorFeedQuery();
     $feed_query->setFilterPHIDs(
       array_merge(
         array($user_phid),
         mpull($projects, 'getPHID')));
 
     // TODO: All this limit stuff should probably be consolidated into the
     // feed query?
 
     $old_link = null;
     $new_link = null;
 
     if ($is_full) {
       $feed_query->setAfter($request->getStr('after'));
       $feed_query->setBefore($request->getStr('before'));
       $limit = 500;
     } else {
       $limit = 100;
     }
 
     // Grab one more story than we intend to display so we can figure out
     // if we need to render an "Older Posts" link or not (with reasonable
     // accuracy, at least).
     $feed_query->setLimit($limit + 1);
     $feed = $feed_query->execute();
     $extra_row = (count($feed) == $limit + 1);
 
     if ($is_full) {
       $have_new = ($request->getStr('before')) ||
                   ($request->getStr('after') && $extra_row);
     } else {
       $have_new = false;
     }
 
     $have_old = ($request->getStr('after')) ||
                 ($request->getStr('before') && $extra_row) ||
                 (!$request->getStr('before') &&
                  !$request->getStr('after') &&
                  $extra_row);
     $feed = array_slice($feed, 0, $limit, $preserve_keys = true);
 
     if ($have_old) {
       $old_link = phutil_render_tag(
         'a',
         array(
           'href' => '/feed/?before='.end($feed)->getChronologicalKey(),
           'class' => 'phabricator-feed-older-link',
         ),
         "Older Stories \xC2\xBB");
     }
     if ($have_new) {
       $new_link = phutil_render_tag(
         'a',
         array(
           'href' => '/feed/?after='.reset($feed)->getChronologicalKey(),
           'class' => 'phabricator-feed-newer-link',
         ),
         "\xC2\xAB Newer Stories");
     }
 
     $builder = new PhabricatorFeedBuilder($feed);
     $builder->setUser($user);
     $feed_view = $builder->buildView();
 
     return
       '<div style="padding: 1em 3em;">'.
         '<div style="margin: 0 1em;">'.
           '<h1 style="font-size: 18px; '.
                      'border-bottom: 1px solid #aaaaaa; '.
                      'padding: 0;">Feed</h1>'.
         '</div>'.
         $feed_view->render().
         '<div class="phabricator-feed-frame">'.
           $new_link.
           $old_link.
         '</div>'.
       '</div>';
   }
 
   private function buildJumpPanel() {
     $request = $this->getRequest();
     $user = $request->getUser();
 
     $uniq_id = celerity_generate_unique_node_id();
 
     Javelin::initBehavior(
       'phabricator-autofocus',
       array(
         'id' => $uniq_id,
       ));
 
     require_celerity_resource('phabricator-jump-nav');
 
-    $doc_href = PhabricatorEnv::getDocLink('articles/Jump_Nav_User_Guide.html');
+    $doc_href = PhabricatorEnv::getDocLink('article/Jump_Nav_User_Guide.html');
     $doc_link = phutil_render_tag(
       'a',
       array(
         'href' => $doc_href,
       ),
       'Jump Nav Use Guide');
 
     $jump_input = phutil_render_tag(
       'input',
       array(
         'type'  => 'text',
         'class' => 'phabricator-jump-nav',
         'name'  => 'jump',
         'id'    => $uniq_id,
       )).
       phutil_render_tag(
         'p',
         array(
           'class' => 'phabricator-jump-nav-caption',
         ),
         'Enter the name of an object like <tt>D123</tt> to quickly jump to '.
         'it. See '.$doc_link.' or type <tt>help</tt>.');
 
     $panel = new AphrontPanelView();
     $panel->appendChild(
       phabricator_render_form(
         $user,
         array(
           'action' => '/jump/',
           'method' => 'POST',
         ),
         $jump_input));
 
     $nav_buttons = array(
       '/maniphest/task/create/' => 'Create a Task',
       '/file/'       => 'Upload a File',
       '/paste/'       => 'Create Paste',
       '/w/'           => 'Browse Wiki',
       '/diffusion/'   => 'Browse Code',
     );
 
     $panel->appendChild('<div class="phabricator-jump-nav-buttons">');
     foreach ($nav_buttons as $uri => $name) {
       $panel->appendChild(
         phutil_render_tag(
           'a',
           array(
             'href' => $uri,
             'class' => 'button grey',
           ),
           phutil_escape_html($name)));
     }
     $panel->appendChild('</div>');
 
     return $panel;
   }
 
 }