Skip to content

Commit

Permalink
add distilled_urls() helper for sitemap generation
Browse files Browse the repository at this point in the history
  • Loading branch information
meeb committed Aug 18, 2024
1 parent 633a46f commit cc8561d
Show file tree
Hide file tree
Showing 4 changed files with 91 additions and 4 deletions.
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -292,6 +292,30 @@ to keep things seperate `django-distill` will also check `settings.LANGUAGES` fo
language codes.


### Sitemaps

You may need to generate a list of all the URLs registered with `django-distill`.
For example, you have a statically generated blog with a few hundred pages and
you want to list all of the URLs easily in a `sitemap.xml` or other similar list
of all URLs. You could wrap your sitemap view in `distill_path` then replicate
all of your URL generation logic by importing your views `distill_func`s from
your `urls.py` and generating these all manually, but given this is quite a hassle
there's a built-in helper to generate all your URLs that will be distilled for you.

```python
from django_distill import distilled_urls

for uri, file_name in distilled_urls():
# URI is the generated, complete URI for the page
print(uri) # for example: /blog/my-post-123/
# file_name is the actual file name on disk, this may be None or a string
print(file_name) # for example: /blog/my-post-123/index.html
```

**Note** that `distilled_urls()` will only return URLs after all of your URLs
in `urls.py` have been loaded with `distill_path(...)`.


# The `distill-local` command

Once you have wrapped the URLs you want to generate statically you can now
Expand Down
6 changes: 6 additions & 0 deletions django_distill/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@

from django import __version__ as django_version
from django_distill.errors import DistillError
from django_distill.distill import urls_to_distill
from django_distill.renderer import generate_urls


try:
Expand Down Expand Up @@ -31,3 +33,7 @@ def distill_path(*args, **kwargs):
err = ('Your installed version of Django ({}) does not supprt '
'django.urls.path, please upgrade')
raise DistillError(err.format(django_version))


def distilled_urls():
return generate_urls(urls_to_distill)
21 changes: 17 additions & 4 deletions django_distill/renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,15 +184,18 @@ def render_file(self, view_name, status_codes, view_args, view_kwargs):
file_name = self._get_filename(file_name, uri, args)
return uri, file_name, render

def render_all_urls(self):
def render_all_urls(self, do_render=True):

def _render(item):
rtn = []
for lang in self.get_langs():
activate_lang(lang)
url, view_name, param_set, status_codes, file_name_base, a, k = item
url, view_name, param_set, status_codes, file_name_base, a, k, do_render = item
uri = self.generate_uri(url, view_name, param_set)
render = self.render_view(uri, status_codes, param_set, a, k)
if do_render:
render = self.render_view(uri, status_codes, param_set, a, k)
else:
render = None
file_name = self._get_filename(file_name_base, uri, param_set)
rtn.append((uri, file_name, render))
return rtn
Expand All @@ -204,7 +207,7 @@ def _render(item):
param_set = ()
elif self._is_str(param_set):
param_set = (param_set,)
to_render.append((url, view_name, param_set, status_codes, file_name_base, a, k))
to_render.append((url, view_name, param_set, status_codes, file_name_base, a, k, do_render))
with ThreadPoolExecutor(max_workers=self.parallel_render) as executor:
results = executor.map(_render, to_render)
for i18n_result in results:
Expand All @@ -223,6 +226,10 @@ def render(self, view_name=None, status_codes=None, view_args=None, view_kwargs=
else:
return self.render_all_urls()

def urls(self):
for (uri, file_name, _) in self.render_all_urls(do_render=False):
yield uri, file_name

def get_langs(self):
langs = []
LANGUAGE_CODE = str(getattr(settings, 'LANGUAGE_CODE', 'en'))
Expand Down Expand Up @@ -475,6 +482,12 @@ def render_single_file(output_dir, view_name, *args, **kwargs):
return True


def generate_urls(urls_to_distill):
load_urls()
renderer = get_renderer(urls_to_distill)
return renderer.urls()


def render_static_redirect(destination_url):
redir = []
redir.append(f'<!DOCTYPE html>')
Expand Down
44 changes: 44 additions & 0 deletions tests/test_renderer.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
from django_distill.distill import urls_to_distill
from django_distill.renderer import DistillRender, render_to_dir, render_single_file, get_renderer
from django_distill.errors import DistillError
from django_distill import distilled_urls


class CustomRender(DistillRender):
Expand Down Expand Up @@ -489,3 +490,46 @@ def _blackhole(_):
for expected_file in expected_files:
filepath = os.path.join(tmpdirname, *expected_file)
self.assertIn(filepath, written_files)

def test_generate_urls(self):
urls = distilled_urls()
generated_urls = []
for url, file_name in urls:
generated_urls.append(url)
expected_urls = (
'/path/namespace1/sub-url-in-namespace',
'/path/namespace1/path/sub-namespace/sub-url-in-sub-namespace',
'/path/no-namespace/sub-url-in-no-namespace',
'/en/path/i18n/sub-url-with-i18n-prefix',
'/re_path/',
'/re_path-no-func/',
'/re_path/12345',
'/re_path/67890',
'/re_path/x/12345',
'/re_path/x/67890',
'/re_path/test',
'/re_path/x/test',
'/re_path/broken',
'/re_path/ignore-sessions',
'/re_path/404',
'/re_path/flatpage/flat/page1.html',
'/re_path/flatpage/flat/page2.html',
'/path/',
'/path-no-func/',
'/path/12345',
'/path/67890',
'/path/x/12345',
'/path/x/67890',
'/path/test',
'/path/x/test',
'/path/broken',
'/path/ignore-sessions',
'/path/404',
'/path/flatpage/flat/page1.html',
'/path/flatpage/flat/page2.html',
'/path/test-sitemap',
'/path/kwargs',
'/path/humanize',
'/path/has-resolver-match'
)
self.assertEqual(sorted(generated_urls), sorted(expected_urls))

0 comments on commit cc8561d

Please sign in to comment.