From 6c0392b28dc9bb4d76791750d66355484e836321 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Denis=20Krienb=C3=BChl?= Date: Mon, 6 Jul 2015 16:03:56 +0200 Subject: [PATCH] Adds the ability to add people to pages --- .../town/locale/de/LC_MESSAGES/onegov.town.po | 11 ++- onegov/town/models/page.py | 77 +++++++++++++++++-- onegov/town/templates/macros.pt | 14 +++- onegov/town/tests/test_views.py | 37 +++++++++ onegov/town/views/editor.py | 8 +- onegov/town/views/form_definition.py | 3 +- onegov/town/views/form_submission.py | 2 +- setup.py | 2 +- 8 files changed, 135 insertions(+), 19 deletions(-) diff --git a/onegov/town/locale/de/LC_MESSAGES/onegov.town.po b/onegov/town/locale/de/LC_MESSAGES/onegov.town.po index 9fa597a..6e87e95 100644 --- a/onegov/town/locale/de/LC_MESSAGES/onegov.town.po +++ b/onegov/town/locale/de/LC_MESSAGES/onegov.town.po @@ -1,7 +1,7 @@ msgid "" msgstr "" "Project-Id-Version: \n" -"POT-Creation-Date: 2015-07-03 13:55+0200\n" +"POT-Creation-Date: 2015-07-06 15:49+0200\n" "PO-Revision-Date: \n" "Last-Translator: Fabian Reinhard \n" "Language-Team: \n" @@ -113,9 +113,6 @@ msgstr "Titel" msgid "URL" msgstr "URL" -msgid "Hide from the public" -msgstr "Vor der Öffentlichkeit verstecken" - msgid "Lead" msgstr "Einleitung" @@ -125,6 +122,12 @@ msgstr "Beschreibt kurz um was es bei diesem Thema geht" msgid "Text" msgstr "Text" +msgid "Hide from the public" +msgstr "Vor der Öffentlichkeit verstecken" + +msgid "Function" +msgstr "Funktion" + msgid "Link" msgstr "Verknüpfung" diff --git a/onegov/town/models/page.py b/onegov/town/models/page.py index ab80172..c1ac2b6 100644 --- a/onegov/town/models/page.py +++ b/onegov/town/models/page.py @@ -1,6 +1,8 @@ from onegov.core import utils from onegov.core.utils import sanitize_html from onegov.form import Form, with_options +from onegov.form.parser.core import WTFormsClassBuilder, FieldDependency +from onegov.people import Person, PersonCollection from onegov.page import Page from onegov.town import _ from onegov.town.models.traitinfo import TraitInfo @@ -38,12 +40,71 @@ def allowed_subtraits(self): def is_supported_trait(self, trait): return trait in {'link', 'page'} - def get_form_class(self, trait): + def with_people(self, form_class, request): + + assert hasattr(form_class, 'get_page') + assert hasattr(form_class, 'set_page') + + class PeoplePageForm(form_class): + + def get_people_fields(self): + return { + f: self._fields[f] for f in self._fields + if f.startswith('people_') and not f.endswith('_function') + } + + def get_page(self, page): + super(PeoplePageForm, self).get_page(page) + + fields = self.get_people_fields() + + ids = {f: v for f, v in fields.items() if v.data is True} + + page.content['people'] = [ + [v.id.hex, self._fields[f + '_function'].data] + for f, v in ids.items() + ] + + def set_page(self, page): + super(PeoplePageForm, self).set_page(page) + + fields = self.get_people_fields() + people = dict(page.content.get('people', [])) + + for field_id, field in fields.items(): + if field.id.hex in people: + self._fields[field_id].data = True + self._fields[field_id + '_function'].data\ + = people[field.id.hex] + + builder = WTFormsClassBuilder(PeoplePageForm) + builder.set_current_fieldset(_("People")) + + query = PersonCollection(request.app.session()).query() + query = query.order_by(Person.first_name, Person.last_name) + + for person in query.all(): + field_id = builder.add_field( + field_class=BooleanField, + label=person.title, + required=False, + id=person.id + ) + builder.add_field( + field_class=StringField, + label=_("Function"), + required=False, + dependency=FieldDependency(field_id, 'y') + ) + + return builder.form_class + + def get_form_class(self, trait, request): if trait == 'link': return LinkForm if trait == 'page': - return PageForm + return self.with_people(PageForm, request) raise NotImplementedError @@ -74,7 +135,7 @@ def allowed_subtraits(self): def is_supported_trait(self, trait): return trait in {'news'} - def get_form_class(self, trait): + def get_form_class(self, trait, request): if trait == 'news': return PageForm @@ -91,12 +152,12 @@ def news_query(self): return query -class PageForm(Form): +class PageBaseForm(Form): """ Defines the base form for all pages. """ title = StringField(_("Title"), [validators.InputRequired()]) -class LinkForm(PageForm): +class LinkForm(PageBaseForm): """ Defines the form for pages with the 'link' trait. """ url = URLField(_("URL"), [validators.InputRequired()]) @@ -111,7 +172,7 @@ def set_page(self, page): self.url.data = page.content.get('url') -class PageForm(PageForm): +class PageForm(PageBaseForm): """ Defines the form for pages with the 'page' trait. """ lead = TextAreaField( label=_("Lead"), @@ -123,7 +184,9 @@ class PageForm(PageForm): widget=with_options(TextArea, class_='editor'), filters=[sanitize_html, mark_images]) - is_hidden_from_public = BooleanField(_("Hide from the public")) + is_hidden_from_public = BooleanField( + label=_("Hide from the public") + ) def get_page(self, page): """ Stores the form values on the page. """ diff --git a/onegov/town/templates/macros.pt b/onegov/town/templates/macros.pt index 76328f1..8b14eb4 100644 --- a/onegov/town/templates/macros.pt +++ b/onegov/town/templates/macros.pt @@ -95,9 +95,17 @@ ${error} diff --git a/onegov/town/tests/test_views.py b/onegov/town/tests/test_views.py index b051bf4..b0b1648 100644 --- a/onegov/town/tests/test_views.py +++ b/onegov/town/tests/test_views.py @@ -699,3 +699,40 @@ def test_people_view(town_app): people = client.get('/personen') assert 'noch keine Personen' in people + + +def test_with_people(town_app): + client = Client(town_app) + + login_page = client.get('/login') + login_page.form.set('email', 'editor@example.org') + login_page.form.set('password', 'hunter2') + login_page.form.submit() + + people = client.get('/personen') + + new_person = people.click('Person') + new_person.form['first_name'] = 'Flash' + new_person.form['last_name'] = 'Gordon' + new_person.form.submit() + + new_person = people.click('Person') + new_person.form['first_name'] = 'Merciless' + new_person.form['last_name'] = 'Ming' + new_person.form.submit() + + new_page = client.get('/themen/leben-wohnen').click('Thema') + + assert 'Flash Gordon' in new_page + assert 'Merciless Ming' in new_page + + new_page.form['title'] = 'About Flash' + new_page.form['people_flash_gordon'] = True + new_page.form['people_flash_gordon_function'] = 'Astronaut' + edit_page = new_page.form.submit().follow().click('Bearbeiten') + + assert edit_page.form['people_flash_gordon'].value == 'y' + assert edit_page.form['people_flash_gordon_function'].value == 'Astronaut' + + assert edit_page.form['people_merciless_ming'].value is None + assert edit_page.form['people_merciless_ming_function'].value == '' diff --git a/onegov/town/views/editor.py b/onegov/town/views/editor.py index 1fc117a..d099dcc 100644 --- a/onegov/town/views/editor.py +++ b/onegov/town/views/editor.py @@ -10,8 +10,12 @@ from onegov.town.models import Editor -@TownApp.form(model=Editor, form=lambda e: e.page.get_form_class(e.trait), - template='form.pt', permission=Private) +def get_form_class(editor, request): + return editor.page.get_form_class(editor.trait, request) + + +@TownApp.form(model=Editor, template='form.pt', permission=Private, + form=get_form_class) def handle_page_form(self, request, form): if self.action == 'new': return handle_new_page(self, request, form) diff --git a/onegov/town/views/form_definition.py b/onegov/town/views/form_definition.py index 418dd76..fe98ddd 100644 --- a/onegov/town/views/form_definition.py +++ b/onegov/town/views/form_definition.py @@ -116,7 +116,8 @@ def handle_new_definition(self, request, form): @TownApp.form(model=FormDefinition, template='form.pt', permission=Private, - form=lambda m: form_classes[m.type], name='bearbeiten') + form=lambda self, request: form_classes[self.type], + name='bearbeiten') def handle_edit_definition(self, request, form): if form.submitted(request): diff --git a/onegov/town/views/form_submission.py b/onegov/town/views/form_submission.py index 3c8dcc4..4f20c85 100644 --- a/onegov/town/views/form_submission.py +++ b/onegov/town/views/form_submission.py @@ -16,7 +16,7 @@ from onegov.town.layout import FormSubmissionLayout -@TownApp.form(model=FormDefinition, form=lambda e: e.form_class, +@TownApp.form(model=FormDefinition, form=lambda self, request: self.form_class, template='form.pt', permission=Public) def handle_defined_form(self, request, form): """ Renders the empty form and takes input, even if it's not valid, stores diff --git a/setup.py b/setup.py index 656049f..669cea2 100644 --- a/setup.py +++ b/setup.py @@ -39,7 +39,7 @@ def get_long_description(): 'jsmin', 'lazy-object-proxy', 'lxml', - 'onegov.core>=0.4.5', + 'onegov.core>=0.4.6', 'onegov.form>=0.6.3', 'onegov.foundation', 'onegov.people>=0.0.1',