[#8388] consolidate markdown_syntax and markdown_syntax_dialog URLs
diff --git a/Allura/allura/controllers/repository.py b/Allura/allura/controllers/repository.py
index 2b34847..54b762e 100644
--- a/Allura/allura/controllers/repository.py
+++ b/Allura/allura/controllers/repository.py
@@ -86,11 +86,6 @@
     def _check_security(self):
         require_access(c.app, 'read')
 
-    @expose('jinja:allura:templates/markdown_syntax_dialog.html')
-    def markdown_syntax_dialog(self, **kw):
-        """Static page explaining markdown."""
-        return dict()
-
     @with_trailing_slash
     @expose()
     def index(self, offset=0, branch=None, **kw):
diff --git a/Allura/allura/controllers/static.py b/Allura/allura/controllers/static.py
index 720ef77..fa0148b 100644
--- a/Allura/allura/controllers/static.py
+++ b/Allura/allura/controllers/static.py
@@ -21,7 +21,7 @@
 
 import six
 from tg import expose
-from tg.decorators import without_trailing_slash
+from tg.decorators import without_trailing_slash, with_trailing_slash
 from webob import exc
 
 from tg import app_globals as g
@@ -57,3 +57,13 @@
         css, md5 = g.tool_icon_css
         return utils.serve_file(
             BytesIO(six.ensure_binary(css)), 'tool_icon_css', 'text/css', etag=md5)
+
+    @expose('jinja:allura:templates/markdown_syntax.html')
+    def markdown_syntax(self, **kw):
+        'Static page explaining markdown.'
+        return dict()
+
+    @expose('jinja:allura:templates/markdown_syntax_dialog.html')
+    def markdown_syntax_dialog(self, **kw):
+        'Static dialog page about how to use markdown.'
+        return dict()
diff --git a/Allura/allura/templates/jinja_master/lib.html b/Allura/allura/templates/jinja_master/lib.html
index f879def..d69d8a6 100644
--- a/Allura/allura/templates/jinja_master/lib.html
+++ b/Allura/allura/templates/jinja_master/lib.html
@@ -230,10 +230,9 @@
 
 {% macro markdown_syntax(id='') %}
 <a class="markdown_syntax_toc_crumb" href="#md_ex_toc{{id}}">Back</a>
-<h1>Markdown Syntax Guide</h1>
 
 <div class="markdown_syntax_section md_ex_toc{{id}}">
-<p>{{config.site_name}} uses markdown syntax everywhere to allow you to create rich<br>text markup, and extends markdown in several ways to allow for quick linking<br>to other artifacts in your project. </p>
+<p>{{config.site_name}} uses markdown syntax everywhere to allow you to create rich text markup, and extends markdown in several ways to allow for quick linking to other artifacts in your project. </p>
 <p>Markdown was created to be easy to read, easy to write, and still readable in plain text format.</p>
 
 <ul class="markdown_syntax_toc">
diff --git a/Allura/allura/templates/markdown_syntax.html b/Allura/allura/templates/markdown_syntax.html
index ffba5aa..d974b01 100644
--- a/Allura/allura/templates/markdown_syntax.html
+++ b/Allura/allura/templates/markdown_syntax.html
@@ -18,9 +18,11 @@
 -#}
 {% extends g.theme.master %}
 
-{% block title %}{{c.project.name}} / {{c.app.config.options.mount_label}} / Markdown Syntax{% endblock %}
+{% block title %}{{config['site_name']}} Markdown Syntax{% endblock %}
 
-{% block header %}Markdown Syntax{% endblock %}
+{% block header %}Markdown Syntax Guide{% endblock %}
+
+{% set hide_left_bar = True %}
 
 {% block content %}
 {{lib.markdown_syntax()}}
diff --git a/Allura/allura/templates/markdown_syntax_dialog.html b/Allura/allura/templates/markdown_syntax_dialog.html
index 9675a53..7c49e76 100644
--- a/Allura/allura/templates/markdown_syntax_dialog.html
+++ b/Allura/allura/templates/markdown_syntax_dialog.html
@@ -18,4 +18,6 @@
 -#}
 <!DOCTYPE html>
 {% import 'allura:templates/jinja_master/lib.html' as lib with context %}
+<h1>Markdown Syntax Guide</h1>
+<hr>
 {{lib.markdown_syntax()}}
diff --git a/Allura/allura/templates/widgets/markdown_edit.html b/Allura/allura/templates/widgets/markdown_edit.html
index 1af3df9..48b1806 100644
--- a/Allura/allura/templates/widgets/markdown_edit.html
+++ b/Allura/allura/templates/widgets/markdown_edit.html
@@ -21,7 +21,7 @@
   <textarea id="{{id or rendered_name}}" name="{{rendered_name}}" class="{{widget.css_class}}" {{widget.j2_attrs(attrs)}}>{{value or ''}}</textarea>
   <div class="modal lightmodal markdown_help" style="display:none">
     {{ g.icons['close'].render(extra_css='close') }}
-    <div class="markdown_help_contents" data-url="{{c.app.url}}markdown_syntax_dialog"></div>
+    <div class="markdown_help_contents" data-url="/nf/markdown_syntax_dialog"></div>
   </div>
   <input type="hidden" class="markdown_project" value="{{c.project.shortname}}">
   <input type="hidden" class="markdown_neighborhood" value="{{c.project.neighborhood._id}}">
diff --git a/Allura/allura/tests/functional/test_newforge.py b/Allura/allura/tests/functional/test_newforge.py
new file mode 100644
index 0000000..cb4a20f
--- /dev/null
+++ b/Allura/allura/tests/functional/test_newforge.py
@@ -0,0 +1,52 @@
+#       Licensed to the Apache Software Foundation (ASF) under one
+#       or more contributor license agreements.  See the NOTICE file
+#       distributed with this work for additional information
+#       regarding copyright ownership.  The ASF licenses this file
+#       to you 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.
+
+from __future__ import unicode_literals
+from __future__ import absolute_import
+
+from six.moves.urllib.parse import quote
+
+from allura.tests import TestController
+from allura.tests import decorators as td
+from allura import model as M
+
+
+class TestNewForgeController(TestController):
+
+    @td.with_wiki
+    def test_markdown_to_html(self):
+        n = M.Neighborhood.query.get(name='Projects')
+        r = self.app.get(
+            '/nf/markdown_to_html?markdown=*aaa*bb[wiki:Home]&project=test&app=bugs&neighborhood=%s' % n._id, validate_chunk=True)
+        assert '<p><em>aaa</em>bb<a class="alink" href="/p/test/wiki/Home/">[wiki:Home]</a></p>' in r, r
+
+        # this happens to trigger an error
+        bad_markdown = '<foo {bar}>'
+        r = self.app.get('/nf/markdown_to_html?markdown=%s&project=test&app=bugs&neighborhood=%s' %
+                         (quote(bad_markdown), n._id))
+        r.mustcontain('The markdown supplied could not be parsed correctly.')
+        r.mustcontain('<pre>&lt;foo {bar}&gt;</pre>')
+
+    def test_markdown_syntax(self):
+        r = self.app.get('/nf/markdown_syntax')
+        r.mustcontain('Markdown Syntax')
+        r.mustcontain('href="http://someurl"')
+
+    def test_markdown_syntax_dialog(self):
+        r = self.app.get('/nf/markdown_syntax_dialog')
+        r.mustcontain('<h1>Markdown Syntax Guide</h1>')
+        r.mustcontain('href="http://someurl"')
diff --git a/Allura/allura/tests/functional/test_root.py b/Allura/allura/tests/functional/test_root.py
index beb49de..3caf217 100644
--- a/Allura/allura/tests/functional/test_root.py
+++ b/Allura/allura/tests/functional/test_root.py
@@ -33,7 +33,6 @@
 import os
 
 import six
-from six.moves.urllib.parse import quote
 
 from tg import tmpl_context as c
 from alluratest.tools import assert_equal, assert_in
@@ -174,20 +173,6 @@
         assert len(
             response.html.findAll('a', {'href': '/adobe/adobe-2/'})) == 1
 
-    @td.with_wiki
-    def test_markdown_to_html(self):
-        n = M.Neighborhood.query.get(name='Projects')
-        r = self.app.get(
-            '/nf/markdown_to_html?markdown=*aaa*bb[wiki:Home]&project=test&app=bugs&neighborhood=%s' % n._id, validate_chunk=True)
-        assert '<p><em>aaa</em>bb<a class="alink" href="/p/test/wiki/Home/">[wiki:Home]</a></p>' in r, r
-
-        # this happens to trigger an error
-        bad_markdown = '<foo {bar}>'
-        r = self.app.get('/nf/markdown_to_html?markdown=%s&project=test&app=bugs&neighborhood=%s' %
-                         (quote(bad_markdown), n._id))
-        r.mustcontain('The markdown supplied could not be parsed correctly.')
-        r.mustcontain('<pre>&lt;foo {bar}&gt;</pre>')
-
     def test_slash_redirect(self):
         self.app.get('/p', status=301)
         self.app.get('/p/', status=302)
diff --git a/Allura/docs/getting_started/using.rst b/Allura/docs/getting_started/using.rst
index b8fb6f3..c77c01c 100644
--- a/Allura/docs/getting_started/using.rst
+++ b/Allura/docs/getting_started/using.rst
@@ -160,4 +160,4 @@
 
 Everything in Allura uses Markdown formatting, with several customizations and macros
 specifically for Allura.  There are "Formatting Help" buttons throughout Allura for
-easy reference to the Markdown syntax.  One such page is https://forge-allura.apache.org/p/allura/wiki/markdown_syntax/
+easy reference to the Markdown syntax.  One such page is https://forge-allura.apache.org/nf/markdown_syntax
diff --git a/ForgeBlog/forgeblog/main.py b/ForgeBlog/forgeblog/main.py
index 2d86e2f..ced04ba 100644
--- a/ForgeBlog/forgeblog/main.py
+++ b/ForgeBlog/forgeblog/main.py
@@ -324,12 +324,6 @@
         notification_tasks.send_usermentions_notification.post(post.index_id(), kw['text'])
         redirect(h.urlquote(h.really_unicode(post.url())))
 
-    @with_trailing_slash
-    @expose('jinja:allura:templates/markdown_syntax_dialog.html')
-    def markdown_syntax_dialog(self, **kw):
-        'Static dialog page about how to use markdown.'
-        return dict()
-
     @expose()
     def _lookup(self, year=None, month=None, name=None, *rest):
         if year is None or month is None or name is None:
diff --git a/ForgeDiscussion/forgediscussion/controllers/root.py b/ForgeDiscussion/forgediscussion/controllers/root.py
index b636f7c..29266fc 100644
--- a/ForgeDiscussion/forgediscussion/controllers/root.py
+++ b/ForgeDiscussion/forgediscussion/controllers/root.py
@@ -39,7 +39,7 @@
 from allura.lib.search import search_app
 from allura.lib import helpers as h
 from allura.lib import validators as v
-from allura.lib.utils import AntiSpam
+from allura.lib.utils import AntiSpam, permanent_redirect
 from allura.lib.decorators import require_post, memorable_forget
 from allura.controllers import BaseController, DispatchIndex
 from allura.controllers.rest import AppRestControllerMixin
@@ -175,16 +175,9 @@
         d['search_comments_disable'] = True
         return d
 
-    @expose('jinja:allura:templates/markdown_syntax.html')
+    @expose()
     def markdown_syntax(self, **kw):
-        'Static page explaining markdown.'
-        return dict()
-
-    @with_trailing_slash
-    @expose('jinja:allura:templates/markdown_syntax_dialog.html')
-    def markdown_syntax_dialog(self, **kw):
-        'Static dialog page about how to use markdown.'
-        return dict()
+        permanent_redirect('/nf/markdown_syntax')
 
     @expose()
     def _lookup(self, id=None, *remainder):
diff --git a/ForgeDiscussion/forgediscussion/forum_main.py b/ForgeDiscussion/forgediscussion/forum_main.py
index d48919f..0bf6043 100644
--- a/ForgeDiscussion/forgediscussion/forum_main.py
+++ b/ForgeDiscussion/forgediscussion/forum_main.py
@@ -197,7 +197,7 @@
                 l = l + forum_links
             l.append(SitemapEntry('Help'))
             l.append(
-                SitemapEntry('Formatting Help', c.app.url + 'markdown_syntax'))
+                SitemapEntry('Formatting Help', '/nf/markdown_syntax', extra_html_attrs={'target': '_blank'}))
             return l
         except Exception:  # pragma no cover
             log.exception('sidebar_menu')
diff --git a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
index 3788a7f..2fe9ccf 100644
--- a/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
+++ b/ForgeDiscussion/forgediscussion/tests/functional/test_forum.py
@@ -379,10 +379,6 @@
         self.app.get('/discussion/search')
         self.app.get('/discussion/search', params=dict(q='foo'))
 
-    def test_render_markdown_syntax(self):
-        r = self.app.get('/discussion/markdown_syntax')
-        assert 'Markdown Syntax' in r
-
     def test_forum_index(self):
         self.app.get('/discussion/testforum/')
         self.app.get('/discussion/testforum/childforum/')
@@ -927,7 +923,7 @@
         assert_in("/p/test/discussion/create_topic/", sidebar_links)
         assert_in("/p/test/discussion/new_forum", sidebar_links)
         assert_in('<h3 class="">Help</h3>', sidebar_menu)
-        assert_in("/p/test/discussion/markdown_syntax", sidebar_links)
+        assert_in("/nf/markdown_syntax", sidebar_links)
         assert_not_in("flag_as_spam", sidebar_links)
         r = self.app.get('/discussion/create_topic/')
         f = r.html.find('form', {'action': '/p/test/discussion/save_new_topic'})
@@ -951,7 +947,7 @@
         assert_in("/p/test/discussion/create_topic/", sidebar_links)
         assert_in("/p/test/discussion/new_forum", sidebar_links)
         assert_in('<h3 class="">Help</h3>', sidebar_menu)
-        assert_in("/p/test/discussion/markdown_syntax", sidebar_links)
+        assert_in("/nf/markdown_syntax", sidebar_links)
         assert_not_in("flag_as_spam", sidebar_menu)
         r = self.app.get('/discussion/create_topic/')
         f = r.html.find('form', {'action': '/p/test/discussion/save_new_topic'})
diff --git a/ForgeGit/forgegit/tests/functional/test_controllers.py b/ForgeGit/forgegit/tests/functional/test_controllers.py
index d8680c2..3a5a474 100644
--- a/ForgeGit/forgegit/tests/functional/test_controllers.py
+++ b/ForgeGit/forgegit/tests/functional/test_controllers.py
@@ -547,10 +547,6 @@
         assert_equal(app_config.options['external_checkout_url'], 'http://foo.bar/baz')
         assert_equal(app_config.options['merge_disabled'], True)
 
-    def test_markdown_syntax_dialog(self):
-        r = self.app.get('/p/test/src-git/markdown_syntax_dialog')
-        assert_in('<h1>Markdown Syntax Guide</h1>', r)
-
     def test_refresh(self):
         r = self.app.get('/p/test/src-git/refresh')
         assert_in('refresh queued', r)
diff --git a/ForgeTracker/forgetracker/tests/functional/test_root.py b/ForgeTracker/forgetracker/tests/functional/test_root.py
index d403d59..d4b325a 100644
--- a/ForgeTracker/forgetracker/tests/functional/test_root.py
+++ b/ForgeTracker/forgetracker/tests/functional/test_root.py
@@ -798,10 +798,6 @@
         create_button = r.html.find('a', attrs={'href': '/p/test/bugs/new/'})
         assert_equal(create_button['class'], ['icon', 'sidebar-disabled'])
 
-    def test_render_markdown_syntax(self):
-        r = self.app.get('/bugs/markdown_syntax')
-        assert_true('Markdown Syntax' in r)
-
     @patch.dict('allura.lib.app_globals.config', markdown_cache_threshold='0')
     def test_cached_convert(self):
         from allura.model.session import artifact_orm_session
diff --git a/ForgeTracker/forgetracker/tracker_main.py b/ForgeTracker/forgetracker/tracker_main.py
index 0604cd5..71073fa 100644
--- a/ForgeTracker/forgetracker/tracker_main.py
+++ b/ForgeTracker/forgetracker/tracker_main.py
@@ -20,14 +20,12 @@
 import logging
 import re
 from datetime import datetime, timedelta
-from functools import partial
 from six.moves.urllib.parse import urlencode, unquote
 from webob import exc
 import json
 import os
 
 # Non-stdlib imports
-import pkg_resources
 from tg import expose, validate, redirect, flash, url, jsonify
 from tg.decorators import with_trailing_slash, without_trailing_slash
 from paste.deploy.converters import aslist
@@ -64,6 +62,7 @@
                                  require_authenticated)
 from allura.lib import widgets as w
 from allura.lib import validators as V
+from allura.lib.utils import permanent_redirect
 from allura.lib.widgets import form_fields as ffw
 from allura.lib.widgets.subscriptions import SubscribeForm
 from allura.lib.plugin import ImportIdConverter
@@ -380,7 +379,7 @@
             links = links + search_bins
         links.append(SitemapEntry('Help'))
         links.append(
-            SitemapEntry('Formatting Help', self.config.url() + 'markdown_syntax'))
+            SitemapEntry('Formatting Help', '/nf/markdown_syntax', extra_html_attrs={'target': '_blank'}))
         return links
 
     def sidebar_menu_js(self):
@@ -905,15 +904,9 @@
                     subscribed_to_tool=M.Mailbox.subscribed(),
                     )
 
-    @expose('jinja:allura:templates/markdown_syntax.html')
+    @expose()
     def markdown_syntax(self, **kw):
-        """Static page explaining markdown."""
-        return dict()
-
-    @expose('jinja:allura:templates/markdown_syntax_dialog.html')
-    def markdown_syntax_dialog(self, **kw):
-        """Static page explaining markdown."""
-        return dict()
+        permanent_redirect('/nf/markdown_syntax')
 
     @memorable_forget()
     @expose()
diff --git a/ForgeWiki/forgewiki/tests/functional/test_root.py b/ForgeWiki/forgewiki/tests/functional/test_root.py
index 4c4f284..5b98fbc 100644
--- a/ForgeWiki/forgewiki/tests/functional/test_root.py
+++ b/ForgeWiki/forgewiki/tests/functional/test_root.py
@@ -73,8 +73,8 @@
         assert 'Create page' in r.text
 
     def test_root_markdown_syntax(self):
-        response = self.app.get('/wiki/markdown_syntax/')
-        assert 'Markdown Syntax' in response
+        response = self.app.get('/wiki/markdown_syntax/', status=301)
+        assert response.location.endswith('/nf/markdown_syntax')
 
     def test_root_browse_tags(self):
         response = self.app.get('/wiki/browse_tags/')
diff --git a/ForgeWiki/forgewiki/wiki_main.py b/ForgeWiki/forgewiki/wiki_main.py
index 4d47311..3b8af16 100644
--- a/ForgeWiki/forgewiki/wiki_main.py
+++ b/ForgeWiki/forgewiki/wiki_main.py
@@ -278,7 +278,7 @@
             links.append(SitemapEntry(subscribe_title, subscribe_url, ui_icon=g.icons['mail']))
         if not admin_menu:
             links += [SitemapEntry(''),
-                      SitemapEntry('Formatting Help', self.url + 'markdown_syntax/')]
+                      SitemapEntry('Formatting Help', '/nf/markdown_syntax', extra_html_attrs={'target': '_blank'})]
         return links
 
     def admin_menu(self, skip_common_menu=False):
@@ -519,17 +519,9 @@
     def create_wiki_page(self, **kw):
         return {}
 
-    @with_trailing_slash
-    @expose('jinja:allura:templates/markdown_syntax.html')
+    @expose()
     def markdown_syntax(self, **kw):
-        'Display a page about how to use markdown.'
-        return dict(example=MARKDOWN_EXAMPLE)
-
-    @with_trailing_slash
-    @expose('jinja:allura:templates/markdown_syntax_dialog.html')
-    def markdown_syntax_dialog(self, **kw):
-        'Display a page about how to use markdown.'
-        return dict(example=MARKDOWN_EXAMPLE)
+        permanent_redirect('/nf/markdown_syntax')
 
     @expose()
     @require_post()
@@ -839,16 +831,6 @@
     AttachmentControllerClass = WikiAttachmentController
 
 
-MARKDOWN_EXAMPLE = '''
-# First-level heading
-
-Some *emphasized* and **strong** text
-
-#### Fourth-level heading
-
-'''
-
-
 class RootRestController(BaseController, AppRestControllerMixin):
 
     def __init__(self):