Skip to content

Commit

Permalink
Allow the url() helper to get a path for a page that will only exist …
Browse files Browse the repository at this point in the history
…in the CMS (#15180)

* Support using the url() helper in a non-CMS page to get a path for a page that will only exist in the CMS

Depends on the CMS page being on a planned/known path in the tree. See the updates to cms.rst for more

* Fix italics in documentation
  • Loading branch information
stevejalim authored Sep 19, 2024
1 parent bc4773b commit 84357af
Show file tree
Hide file tree
Showing 3 changed files with 72 additions and 1 deletion.
16 changes: 15 additions & 1 deletion bedrock/base/templatetags/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

from django.conf import settings
from django.contrib.staticfiles.storage import staticfiles_storage
from django.urls import NoReverseMatch
from django.utils.encoding import smart_str

import jinja2
Expand Down Expand Up @@ -60,7 +61,20 @@ def thisyear():
@library.global_function
def url(viewname, *args, **kwargs):
"""Helper for Django's ``reverse`` in templates."""
return reverse(viewname, args=args, kwargs=kwargs)

try:
# First, look for URLs which only exist in the CMS - these are solely defined
# in bedrock/cms/cms_only_urls.py. These URLs are not listed in
# the main URLConf because they aren't served by the Django views in
# bedrock, but they will/must have matching routes set up in the CMS.
return reverse(
viewname,
urlconf="bedrock.cms.cms_only_urls",
args=args,
kwargs=kwargs,
)
except NoReverseMatch:
return reverse(viewname, args=args, kwargs=kwargs)


@library.filter
Expand Down
29 changes: 29 additions & 0 deletions bedrock/cms/cms_only_urls.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# This Source Code Form is subject to the terms of the Mozilla Public
# License, v. 2.0. If a copy of the MPL was not distributed with this
# file, You can obtain one at https://mozilla.org/MPL/2.0/.

# This module contains named URL paths which only exist in the CMS.
#
# They are named so that they can be looked up via our url() jinja
# helper, even though the actual page exists in the CMS only.
#
# These URLs will/must have matching routes set up in the CMS pages
# else they will lead to a 404 from the CMS.
#
# Note that all URL routes defined here should point to the
# dummy_view function, which never gets called because this
# urlconf is only use with reverse(), never resolve()


# from django.urls import path


def dummy_view(*args, **kwargs):
# This view will never get called
pass


urlpatterns = (
# pattern is:
# path("url/path/here", dummy_view, name="route.name.here")
)
28 changes: 28 additions & 0 deletions docs/cms.rst
Original file line number Diff line number Diff line change
Expand Up @@ -423,6 +423,33 @@ views in the URLconf. It can also be passed to our very handy

For more details, please see the docstring on ``bedrock.cms.decorators.prefer_cms``.


Generating URLs for CMS pages in non-CMS templates
==================================================

Pages in the CMS don't appear in the hard-coded URLConfs in Bedrock. Normally,
this means there's no way to use `url()` to generate a path to it.

However, if there's a page in the CMS you need to generate a URL for using
the ``url()`` template tag, `and you know what its path will be`, Bedrock contains
a solution.

``bedrock.cms.cms_only_urls`` is a special URLConf that only gets loaded during
the call to the ``url()`` helper. If you expand it with a named route definition
that matches the path you know will/should exist in the CMS (and most of our
CMS-backed pages `do` have carefully curated paths), the ``url()`` helper will
give you a path that points to that page, even though it doesn't really exist
as a static Django view.

See the example in the ``bedrock.cms.cms_only_urls.py`` file.

.. note::
Moving a URL route to ``cms_only_urls.py`` is a natural next step after
you've migrated a page to the CMS using the ``@prefer_cms`` decorator
and now want to remove the old view without breaking all the calls to
`url('some.view')` or `reverse('some.view')`.


Images
======

Expand Down Expand Up @@ -502,6 +529,7 @@ By default, the sqlite DB you can download to run bedrock locally is based on th
Bedrock Dev. To get images from the cloud bucket for dev, run:

.. code-block:: shell
./manage.py download_media_to_local
This will look at your local DB, find the image files that it says should be
Expand Down

0 comments on commit 84357af

Please sign in to comment.