diff options
Diffstat (limited to 'pydis_site/apps/home')
-rw-r--r-- | pydis_site/apps/home/templatetags/extra_filters.py | 2 | ||||
-rw-r--r-- | pydis_site/apps/home/templatetags/wiki_extra.py | 132 | ||||
-rw-r--r-- | pydis_site/apps/home/tests/test_wiki_templatetags.py | 238 | ||||
-rw-r--r-- | pydis_site/apps/home/urls.py | 8 |
4 files changed, 2 insertions, 378 deletions
diff --git a/pydis_site/apps/home/templatetags/extra_filters.py b/pydis_site/apps/home/templatetags/extra_filters.py index d63b3245..89b45831 100644 --- a/pydis_site/apps/home/templatetags/extra_filters.py +++ b/pydis_site/apps/home/templatetags/extra_filters.py @@ -11,7 +11,7 @@ def starts_with(value: str, arg: str) -> bool: Usage: ```django - {% if request.url | starts_with:"/wiki" %} + {% if request.url | starts_with:"/events" %} ... {% endif %} ``` diff --git a/pydis_site/apps/home/templatetags/wiki_extra.py b/pydis_site/apps/home/templatetags/wiki_extra.py deleted file mode 100644 index b4b720bf..00000000 --- a/pydis_site/apps/home/templatetags/wiki_extra.py +++ /dev/null @@ -1,132 +0,0 @@ -from typing import Any, Dict, List, Type, Union - -from django import template -from django.forms import BooleanField, BoundField, CharField, Field, ImageField, ModelChoiceField -from django.template import Context -from django.template.loader import get_template -from django.utils.safestring import SafeText, mark_safe -from wiki.editors.markitup import MarkItUpWidget -from wiki.forms import WikiSlugField -from wiki.models import URLPath -from wiki.plugins.notifications.forms import SettingsModelChoiceField - -TEMPLATE_PATH = "wiki/forms/fields/{0}.html" - -TEMPLATES: Dict[Type, str] = { - BooleanField: TEMPLATE_PATH.format("boolean"), - CharField: TEMPLATE_PATH.format("char"), - ImageField: TEMPLATE_PATH.format("image"), - - ModelChoiceField: TEMPLATE_PATH.format("model_choice"), - SettingsModelChoiceField: TEMPLATE_PATH.format("model_choice"), - WikiSlugField: TEMPLATE_PATH.format("wiki_slug_render"), -} - - -register = template.Library() - - -def get_unbound_field(field: Union[BoundField, Field]) -> Field: - """ - Unwraps a bound Django Forms field, returning the unbound field. - - Bound fields often don't give you the same level of access to the field's underlying attributes, - so sometimes it helps to have access to the underlying field object. - """ - while isinstance(field, BoundField): - field = field.field - - return field - - -def render(template_path: str, context: Dict[str, Any]) -> SafeText: - """ - Renders a template at a specified path, with the provided context dictionary. - - This was extracted mostly for the sake of mocking it out in the tests - but do note that - the resulting rendered template is wrapped with `mark_safe`, so it will not be escaped. - """ - return mark_safe(get_template(template_path).render(context)) # noqa: S703, S308 - - -def render_field(field: Field, render_labels: bool = True) -> SafeText: - """ - Renders a form field using a custom template designed specifically for the wiki forms. - - As the wiki uses custom form rendering logic, we were unable to make use of Crispy Forms for - it. This means that, in order to customize the form fields, we needed to be able to render - the fields manually. This function handles that logic. - - Sometimes we don't want to render the label that goes with a field - the `render_labels` - argument defaults to True, but can be set to False if the label shouldn't be rendered. - - The label rendering logic is left up to the template. - - Usage: `{% render_field field_obj [render_labels=True/False] %}` - """ - unbound_field = get_unbound_field(field) - - if not isinstance(render_labels, bool): - render_labels = True - - template_path = TEMPLATES.get(unbound_field.__class__, TEMPLATE_PATH.format("in_place_render")) - is_markitup = isinstance(unbound_field.widget, MarkItUpWidget) - context = {"field": field, "is_markitup": is_markitup, "render_labels": render_labels} - - return render(template_path, context) - - [email protected]_tag(takes_context=True) -def get_field_options(context: Context, field: BoundField) -> str: - """ - Retrieves the field options for a multiple choice field, and stores it in the context. - - This tag exists because we can't call functions within Django templates directly, and is - only made use of in the template for ModelChoice (and derived) fields - but would work fine - with anything that makes use of your standard `<select>` element widgets. - - This stores the parsed options under `options` in the context, which will subsequently - be available in the template. - - Usage: - - ```django - {% get_field_options field_object %} - - {% if options %} - {% for group_name, group_choices, group_index in options %} - ... - {% endfor %} - {% endif %} - ``` - """ - widget = field.field.widget - - if field.value() is None: - value: List[str] = [] - else: - value = [str(field.value())] - - context["options"] = widget.optgroups(field.name, value) - return "" - - -def render_urlpath(value: Union[URLPath, str]) -> str: - """ - Simple filter to render a URLPath (or string) into a template. - - This is used where the wiki intends to render a path - mostly because if you just - `str(url_path)`, you'll actually get a path that starts with `(root)` instead of `/`. - - We support strings here as well because the wiki is very inconsistent about when it - provides a string versus when it provides a URLPath, and it was too much work to figure out - and account for it in the templates. - - Usage: `{{ url_path | render_urlpath }}` - """ - if isinstance(value, str): - return value or "/" - - return value.path or "/" diff --git a/pydis_site/apps/home/tests/test_wiki_templatetags.py b/pydis_site/apps/home/tests/test_wiki_templatetags.py deleted file mode 100644 index e1e2a02c..00000000 --- a/pydis_site/apps/home/tests/test_wiki_templatetags.py +++ /dev/null @@ -1,238 +0,0 @@ -from unittest.mock import Mock, create_autospec - -from django.forms import ( - BooleanField, BoundField, CharField, ChoiceField, Field, Form, ImageField, - ModelChoiceField -) -from django.template import Context, Template -from django.test import TestCase -from wiki.editors.markitup import MarkItUpWidget -from wiki.forms import WikiSlugField -from wiki.models import Article, URLPath as _URLPath -from wiki.plugins.notifications.forms import SettingsModelChoiceField - -from pydis_site.apps.home.templatetags import wiki_extra - -URLPath = Mock(_URLPath) - - -class TestURLPathFilter(TestCase): - TEMPLATE = Template( - """ - {% load wiki_extra %} - {{ obj|render_urlpath }} - """ - ) - - def test_str(self): - context = {"obj": "/path/"} - rendered = self.TEMPLATE.render(Context(context)) - - self.assertEqual(rendered.strip(), "/path/") - - def test_str_empty(self): - context = {"obj": ""} - rendered = self.TEMPLATE.render(Context(context)) - - self.assertEqual(rendered.strip(), "/") - - def test_urlpath(self): - url_path = URLPath() - url_path.path = "/path/" - - context = {"obj": url_path} - rendered = self.TEMPLATE.render(Context(context)) - - self.assertEqual(rendered.strip(), "/path/") - - def test_urlpath_root(self): - url_path = URLPath() - url_path.path = None - - context = {"obj": url_path} - rendered = self.TEMPLATE.render(Context(context)) - - self.assertEqual(rendered.strip(), "/") - - -class TestRenderField(TestCase): - TEMPLATE = Template( - """ - {% load wiki_extra %} - {% render_field field %} - """ - ) - - TEMPLATE_NO_LABELS = Template( - """ - {% load wiki_extra %} - {% render_field field render_labels=False %} - """ - ) - - TEMPLATE_LABELS_NOT_BOOLEAN = Template( - """ - {% load wiki_extra %} - {% render_field field render_labels="" %} - """ - ) - - def test_bound_field(self): - unbound_field = Field() - field = BoundField(Form(), unbound_field, "field") - - context = Context({"field": field}) - self.TEMPLATE.render(context) - - def test_bound_field_no_labels(self): - unbound_field = Field() - field = BoundField(Form(), unbound_field, "field") - - context = Context({"field": field}) - self.TEMPLATE_NO_LABELS.render(context) - - def test_bound_field_labels_not_boolean(self): - unbound_field = Field() - field = BoundField(Form(), unbound_field, "field") - - context = Context({"field": field}) - self.TEMPLATE_LABELS_NOT_BOOLEAN.render(context) - - def test_unbound_field(self): - field = Field() - - context = Context({"field": field}) - self.TEMPLATE.render(context) - - def test_unbound_field_no_labels(self): - field = Field() - - context = Context({"field": field}) - self.TEMPLATE_NO_LABELS.render(context) - - def test_unbound_field_labels_not_boolean(self): - field = Field() - - context = Context({"field": field}) - self.TEMPLATE_LABELS_NOT_BOOLEAN.render(context) - - -class TestRenderFieldTypes(TestCase): - TEMPLATE = Template( - """ - {% load wiki_extra %} - {% render_field field %} - """ - ) - - @classmethod - def setUpClass(cls): - cls._wiki_extra_render = wiki_extra.render - wiki_extra.render = create_autospec(wiki_extra.render, return_value="") - - @classmethod - def tearDownClass(cls): - wiki_extra.render = cls._wiki_extra_render - del cls._wiki_extra_render - - def test_field_boolean(self): - field = BooleanField() - - context = Context({"field": field}) - self.TEMPLATE.render(context) - - template_path = "wiki/forms/fields/boolean.html" - context = {"field": field, "is_markitup": False, "render_labels": True} - - wiki_extra.render.assert_called_with(template_path, context) - - def test_field_char(self): - field = CharField() - field.widget = None - - context = Context({"field": field}) - self.TEMPLATE.render(context) - - template_path = "wiki/forms/fields/char.html" - context = {"field": field, "is_markitup": False, "render_labels": True} - - wiki_extra.render.assert_called_with(template_path, context) - - def test_field_char_markitup(self): - field = CharField() - field.widget = MarkItUpWidget() - - context = Context({"field": field}) - self.TEMPLATE.render(context) - - template_path = "wiki/forms/fields/char.html" - context = {"field": field, "is_markitup": True, "render_labels": True} - - wiki_extra.render.assert_called_with(template_path, context) - - def test_field_image(self): - field = ImageField() - - context = Context({"field": field}) - self.TEMPLATE.render(context) - - template_path = "wiki/forms/fields/image.html" - context = {"field": field, "is_markitup": False, "render_labels": True} - - wiki_extra.render.assert_called_with(template_path, context) - - def test_field_model_choice(self): - field = ModelChoiceField(Article.objects.all()) - - context = Context({"field": field}) - self.TEMPLATE.render(context) - - template_path = "wiki/forms/fields/model_choice.html" - context = {"field": field, "is_markitup": False, "render_labels": True} - - wiki_extra.render.assert_called_with(template_path, context) - - def test_field_settings_model_choice(self): - field = SettingsModelChoiceField(Article.objects.all()) - - context = Context({"field": field}) - self.TEMPLATE.render(context) - - template_path = "wiki/forms/fields/model_choice.html" - context = {"field": field, "is_markitup": False, "render_labels": True} - - wiki_extra.render.assert_called_with(template_path, context) - - def test_field_wiki_slug(self): - field = WikiSlugField() - - context = Context({"field": field}) - self.TEMPLATE.render(context) - - template_path = "wiki/forms/fields/wiki_slug_render.html" - context = {"field": field, "is_markitup": False, "render_labels": True} - - wiki_extra.render.assert_called_with(template_path, context) - - -class TestGetFieldOptions(TestCase): - TEMPLATE = Template( - """ - {% load wiki_extra %} - {% get_field_options field %} - """ - ) - - def test_get_field_options(self): - unbound_field = ChoiceField() - field = BoundField(Form(), unbound_field, "field") - - context = Context({"field": field}) - self.TEMPLATE.render(context) - - def test_get_field_options_value(self): - unbound_field = ChoiceField() - field = BoundField(Form(initial={"field": "Value"}), unbound_field, "field") - - context = Context({"field": field}) - self.TEMPLATE.render(context) diff --git a/pydis_site/apps/home/urls.py b/pydis_site/apps/home/urls.py index ed8dcfe6..09b5df34 100644 --- a/pydis_site/apps/home/urls.py +++ b/pydis_site/apps/home/urls.py @@ -1,6 +1,4 @@ from allauth.account.views import LogoutView -from django.conf import settings -from django.conf.urls.static import static from django.contrib import admin from django.contrib.messages import ERROR from django.urls import include, path @@ -14,8 +12,6 @@ urlpatterns = [ path('', HomeView.as_view(), name='home'), path('', HomeView.as_view(), name='socialaccount_connections'), - path('pages/', include('wiki.urls')), - path('accounts/', include('allauth.socialaccount.providers.discord.urls')), path('accounts/', include('allauth.socialaccount.providers.github.urls')), @@ -37,7 +33,5 @@ urlpatterns = [ path('logout', LogoutView.as_view(), name="logout"), path('admin/', admin.site.urls), - path('notifications/', include('django_nyt.urls')), - path('resources/', include('pydis_site.apps.resources.urls', namespace="resources")), -] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) +] |