diff options
author | 2019-04-20 23:49:12 +0200 | |
---|---|---|
committer | 2019-04-20 23:49:12 +0200 | |
commit | 0e373cd953dd7ee8433cd936a8df050ab097bb08 (patch) | |
tree | 54061f3d1f33247f0a57efc311167ba275c67c94 /pydis_site/apps/home | |
parent | Merge pull request #213 from python-discord/django_front_page (diff) | |
parent | Replace wiki dep with PyDis fork, add git to Docker (diff) |
Merge pull request #202 from gdude2002/django+200/wiki
[#200] Django Wiki
Diffstat (limited to 'pydis_site/apps/home')
-rw-r--r-- | pydis_site/apps/home/templatetags/wiki_extra.py | 72 | ||||
-rw-r--r-- | pydis_site/apps/home/tests/test_wiki_templatetags.py | 238 | ||||
-rw-r--r-- | pydis_site/apps/home/urls.py | 10 |
3 files changed, 317 insertions, 3 deletions
diff --git a/pydis_site/apps/home/templatetags/wiki_extra.py b/pydis_site/apps/home/templatetags/wiki_extra.py new file mode 100644 index 00000000..289b0279 --- /dev/null +++ b/pydis_site/apps/home/templatetags/wiki_extra.py @@ -0,0 +1,72 @@ +from typing import Any, Dict, 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 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: + while isinstance(field, BoundField): + field = field.field + + return field + + +def render(template_path: str, context: Dict[str, Any]): + return mark_safe(get_template(template_path).render(context)) # noqa: S703 S308 + + +def render_field(field: Field, render_labels: bool = True): + 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): + widget = field.field.widget + + if field.value() is None: + value = [] + else: + value = [str(field.value())] + + context["options"] = widget.optgroups(field.name, value) + return "" + + +def render_urlpath(value: Union[URLPath, str]): + 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 new file mode 100644 index 00000000..e1e2a02c --- /dev/null +++ b/pydis_site/apps/home/tests/test_wiki_templatetags.py @@ -0,0 +1,238 @@ +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 d8dba2f6..b22508d9 100644 --- a/pydis_site/apps/home/urls.py +++ b/pydis_site/apps/home/urls.py @@ -1,10 +1,14 @@ +from django.conf import settings +from django.conf.urls.static import static from django.contrib import admin -from django.urls import path +from django.urls import include, path from .views import HomeView app_name = 'home' urlpatterns = [ path('', HomeView.as_view(), name='home'), - path('admin/', admin.site.urls) -] + path('admin/', admin.site.urls), + path('notifications/', include('django_nyt.urls')), + path('wiki/', include('wiki.urls')), +] + static(settings.MEDIA_URL, document_root=settings.MEDIA_ROOT) |