From e4f35319739efccaf236580f073e8d285e000376 Mon Sep 17 00:00:00 2001 From: Sydo Luciani <60237469+sydoluciani@users.noreply.github.com> Date: Thu, 22 Oct 2020 21:38:44 -0500 Subject: [PATCH 01/11] Include unofficial-deformdemo --- deformdemo/__init__.py | 3 +++ 1 file changed, 3 insertions(+) diff --git a/deformdemo/__init__.py b/deformdemo/__init__.py index b24a71f3..fb4d38aa 100644 --- a/deformdemo/__init__.py +++ b/deformdemo/__init__.py @@ -2901,4 +2901,7 @@ def onerror(*arg): pass config.scan("deformdemo", onerror=onerror) + + config.include('..unofficial-deformdemo') + return config.make_wsgi_app() From b75bb6d2c375c6e203099767c356802027a321ce Mon Sep 17 00:00:00 2001 From: Sydo Luciani <60237469+sydoluciani@users.noreply.github.com> Date: Thu, 22 Oct 2020 21:39:28 -0500 Subject: [PATCH 02/11] Add unofficial-deformdemo module. --- unofficial-deformdemo/__init__.py | 2 ++ 1 file changed, 2 insertions(+) create mode 100644 unofficial-deformdemo/__init__.py diff --git a/unofficial-deformdemo/__init__.py b/unofficial-deformdemo/__init__.py new file mode 100644 index 00000000..16392bcb --- /dev/null +++ b/unofficial-deformdemo/__init__.py @@ -0,0 +1,2 @@ +def includeme(config): + pass From 5eb5e45c3e82de2b827e3d124115b33dd291ac13 Mon Sep 17 00:00:00 2001 From: Sydo Luciani <60237469+sydoluciani@users.noreply.github.com> Date: Fri, 23 Oct 2020 15:37:50 -0500 Subject: [PATCH 03/11] Add templates directories. --- deformdemo/__init__.py | 5 +- unofficial-deformdemo/__init__.py | 232 +++++++++++++++++- unofficial-deformdemo/templates/code.pt | 6 + unofficial-deformdemo/templates/form.pt | 46 ++++ unofficial-deformdemo/templates/index.pt | 31 +++ unofficial-deformdemo/templates/main.pt | 93 +++++++ unofficial-deformdemo/templates/mini.pt | 66 +++++ .../templates/popup_example.pt | 65 +++++ 8 files changed, 542 insertions(+), 2 deletions(-) create mode 100644 unofficial-deformdemo/templates/code.pt create mode 100644 unofficial-deformdemo/templates/form.pt create mode 100644 unofficial-deformdemo/templates/index.pt create mode 100644 unofficial-deformdemo/templates/main.pt create mode 100644 unofficial-deformdemo/templates/mini.pt create mode 100644 unofficial-deformdemo/templates/popup_example.pt diff --git a/deformdemo/__init__.py b/deformdemo/__init__.py index fb4d38aa..6f92b65e 100644 --- a/deformdemo/__init__.py +++ b/deformdemo/__init__.py @@ -2892,7 +2892,10 @@ def translator(term): return get_localizer(get_current_request()).translate(term) # Configure renderer - configure_zpt_renderer(("deformdemo:custom_widgets",), translator) + configure_zpt_renderer( + ("deformdemo:custom_widgets", "unofficial-deformdemo:custom_widgets"), + translator, + ) config.add_static_view("static_deform", "deform:static") config.add_route("deformdemo", "*traverse") diff --git a/unofficial-deformdemo/__init__.py b/unofficial-deformdemo/__init__.py index 16392bcb..91d4f53c 100644 --- a/unofficial-deformdemo/__init__.py +++ b/unofficial-deformdemo/__init__.py @@ -1,2 +1,232 @@ +# -*- coding: utf-8 -*- + +""" A Pyramid app that demonstrates various Deform widgets and +capabilities and which provides a functional test suite """ + +import inspect +import logging +import pprint +import sys + +import colander +from pyramid.i18n import TranslationStringFactory +from pyramid.i18n import get_locale_name +from pyramid.renderers import get_renderer +from pyramid.response import Response +from pyramid.view import view_config +from pyramid.view import view_defaults + +import deform +from pygments import highlight +from pygments.formatters import HtmlFormatter +from pygments.lexers import PythonLexer + + +log = logging.getLogger(__name__) + + +PY3 = sys.version_info[0] == 3 +PY38MIN = sys.version_info[0] == 3 and sys.version_info[1] >= 8 + +if PY3: + + def unicode(val, encoding="utf-8"): + return val + + +_ = TranslationStringFactory("deformdemo") + +formatter = HtmlFormatter(nowrap=True) +css = formatter.get_style_defs() + +# the zpt_renderer above is referred to within the demo.ini file by dotted name + + +class demonstrate(object): + def __init__(self, title): + self.title = title + + def __call__(self, method): + method.demo = self.title + return method + + +# Py2/Py3 compat +# http://stackoverflow.com/a/16888673/315168 +# eliminate u'' +def my_safe_repr(obj, context, maxlevels, level, sort_dicts=True): + + if type(obj) == unicode: + obj = obj.encode("utf-8") + + # Python 3.8 changed the call signature of pprint._safe_repr. + # by adding sort_dicts. + if PY38MIN: + return pprint._safe_repr(obj, context, maxlevels, level, sort_dicts) + else: + return pprint._safe_repr(obj, context, maxlevels, level) + + +@view_defaults(route_name="deformdemo") +class DeformDemo(object): + def __init__(self, request): + self.request = request + self.macros = get_renderer("templates/main.pt").implementation().macros + + def render_form( + self, + form, + appstruct=colander.null, + submitted="submit", + success=None, + readonly=False, + is_i18n=False, + ): + + captured = None + + if submitted in self.request.POST: + # the request represents a form submission + try: + # try to validate the submitted values + controls = self.request.POST.items() + captured = form.validate(controls) + if success: + response = success() + if response is not None: + return response + html = form.render(captured) + except deform.ValidationFailure as e: + # the submitted values could not be validated + html = e.render() + + else: + # the request requires a simple form rendering + html = form.render(appstruct, readonly=readonly) + + if self.request.is_xhr: + return Response(html) + + code, start, end = self.get_code(2) + locale_name = get_locale_name(self.request) + + reqts = form.get_widget_resources() + + printer = pprint.PrettyPrinter() + printer.format = my_safe_repr + output = printer.pformat(captured) + captured = highlight(output, PythonLexer(), formatter) + + # values passed to template for rendering + return { + "form": html, + "captured": captured, + "code": code, + "start": start, + "end": end, + "is_i18n": is_i18n, + "locale": locale_name, + "demos": self.get_demos(), + "title": self.get_title(), + "css_links": reqts["css"], + "js_links": reqts["js"], + } + + def get_code(self, level): + frame = sys._getframe(level) + lines, start = inspect.getsourcelines(frame.f_code) + end = start + len(lines) + code = "".join(lines) + if not PY3: + code = unicode(code, "utf-8") + return highlight(code, PythonLexer(), formatter), start, end + + @view_config(name="thanks.html") + def thanks(self): + return Response( + "
Thanks!
" + 'Up' + ) + + @view_config(name="allcode", renderer="templates/code.pt") + def allcode(self): + params = self.request.params + start = params.get("start") + end = params.get("end") + hl_lines = None + if start and end: + start = int(start) + end = int(end) + hl_lines = list(range(start, end)) + code = open(inspect.getsourcefile(self.__class__), "r").read() + code = code.encode("utf-8") + formatter = HtmlFormatter( + linenos="table", + lineanchors="line", + cssclass="hightlight ", + hl_lines=hl_lines, + ) + html = highlight(code, PythonLexer(), formatter) + return {"code": html, "demos": self.get_demos()} + + def get_title(self): + # gross hack; avert your eyes + frame = sys._getframe(3) + attr = frame.f_locals["attr"] + inst = frame.f_locals["inst"] + method = getattr(inst, attr) + return method.demo + + @view_config(name="pygments.css") + def cssview(self): + response = Response(body=css, content_type="text/css") + response.cache_expires = 360 + return response + + @view_config(renderer="templates/index.pt") + def index(self): + return {"demos": self.get_demos()} + + def get_demos(self): + def predicate(value): + if getattr(value, "demo", None) is not None: + return True + + demos = inspect.getmembers(self, predicate) + L = [] + for name, method in demos: + url = self.request.resource_url( + self.request.root, name, route_name="deformdemo" + ) + L.append((method.demo, url)) + L.sort() + return L + + @view_config(renderer="templates/form.pt", name="textinput") + @demonstrate("Text Input Widget") + def textinput(self): + class Schema(colander.Schema): + text = colander.SchemaNode( + colander.String(), + validator=colander.Length(max=100), + widget=deform.widget.TextInputWidget(), + description="Enter some text", + ) + + schema = Schema() + form = deform.Form(schema, buttons=("submit",)) + + return self.render_form(form) + + def includeme(config): - pass + + # Configure renderer + config.add_static_view( + "static_unofficial-deformdemo", "unofficial-deformdemo:static" + ) + config.add_route( + "unofficial-deformdemo", "/unofficial-deformdemo*traverse" + ) + + config.scan("unofficial-deformdemo") diff --git a/unofficial-deformdemo/templates/code.pt b/unofficial-deformdemo/templates/code.pt new file mode 100644 index 00000000..438404e4 --- /dev/null +++ b/unofficial-deformdemo/templates/code.pt @@ -0,0 +1,6 @@ ++ This demo is written using Pyramid. Note that Deform does + not depend on any particular web framework, + we just had to write a demo application in something. + If you would like to run this demo application locally, + please read the README + file for installation of this application. +
+ ++ For further information, see + the Deform documentation. +
+ +Thanks!
" 'Up' ) - @view_config(name="allcode", renderer="templates/code.pt") + @view_config(name="allcode", + renderer="templates/code.pt", + route_name='unofficial-deformdemo') def allcode(self): params = self.request.params start = params.get("start") @@ -177,13 +179,14 @@ def get_title(self): method = getattr(inst, attr) return method.demo - @view_config(name="pygments.css") + @view_config(name="pygments.css", route_name='unofficial-deformdemo') def cssview(self): response = Response(body=css, content_type="text/css") response.cache_expires = 360 return response - @view_config(renderer="templates/index.pt") + @view_config(renderer="templates/index.pt", + route_name='unofficial-deformdemo') def index(self): return {"demos": self.get_demos()} @@ -196,13 +199,17 @@ def predicate(value): L = [] for name, method in demos: url = self.request.resource_url( - self.request.root, name, route_name="deformdemo" + self.request.root, name, route_name="unofficial-deformdemo" ) L.append((method.demo, url)) L.sort() return L - @view_config(renderer="templates/form.pt", name="textinput") + # Unofficial Deform Demo Forms Starts Here. + + @view_config(name="textinput", + renderer="templates/form.pt", + route_name='unofficial-deformdemo') @demonstrate("Text Input Widget") def textinput(self): class Schema(colander.Schema): @@ -221,12 +228,4 @@ class Schema(colander.Schema): def includeme(config): - # Configure renderer - config.add_static_view( - "static_unofficial-deformdemo", "unofficial-deformdemo:static" - ) - config.add_route( - "unofficial-deformdemo", "/unofficial-deformdemo*traverse" - ) - config.scan("unofficial-deformdemo") diff --git a/unofficial-deformdemo/templates/main.pt b/unofficial-deformdemo/templates/main.pt index a7ace947..5e11d36b 100644 --- a/unofficial-deformdemo/templates/main.pt +++ b/unofficial-deformdemo/templates/main.pt @@ -10,11 +10,11 @@Thanks!
" @@ -150,7 +150,7 @@ def thanks(self): @view_config(name="allcode", renderer="templates/code.pt", - route_name='unofficial-deformdemo') + route_name="unofficial-deformdemo") def allcode(self): params = self.request.params start = params.get("start") @@ -179,14 +179,14 @@ def get_title(self): method = getattr(inst, attr) return method.demo - @view_config(name="pygments.css", route_name='unofficial-deformdemo') + @view_config(name="pygments.css", route_name="unofficial-deformdemo") def cssview(self): response = Response(body=css, content_type="text/css") response.cache_expires = 360 return response @view_config(renderer="templates/index.pt", - route_name='unofficial-deformdemo') + route_name="unofficial-deformdemo") def index(self): return {"demos": self.get_demos()} @@ -205,11 +205,11 @@ def predicate(value): L.sort() return L - # Unofficial Deform Demo Forms Starts Here. + # Unofficial Deform Demo Forms Start Here. @view_config(name="textinput", renderer="templates/form.pt", - route_name='unofficial-deformdemo') + route_name="unofficial-deformdemo") @demonstrate("Text Input Widget") def textinput(self): class Schema(colander.Schema): From 5ad01b1f87df3043f1804e47d9ae3ff6fefb3413 Mon Sep 17 00:00:00 2001 From: Steve PiercyThe official Deform Demo supports tested and documented widgets. + The unofficial Deform Demo provides a space for contributors to add custom widgets that are not supported with the usual rigorous tests and documentation that is required by the Pylons Project.
This demo is written using Pyramid. Note that Deform does - not depend on any particular web framework, - we just had to write a demo application in something. + not depend on any particular web framework. + We had to write a demo application in something. If you would like to run this demo application locally, please read the README file for installation of this application. diff --git a/deformdemo/templates/main.pt b/deformdemo/templates/main.pt index a7ace947..a7587341 100644 --- a/deformdemo/templates/main.pt +++ b/deformdemo/templates/main.pt @@ -60,9 +60,14 @@
diff --git a/unofficial-deformdemo/templates/index.pt b/unofficial-deformdemo/templates/index.pt index 5e5069b9..745a7739 100644 --- a/unofficial-deformdemo/templates/index.pt +++ b/unofficial-deformdemo/templates/index.pt @@ -3,17 +3,20 @@The official Deform Demo supports tested and documented widgets. + The unofficial Deform Demo provides a space for contributors to add custom widgets that are not supported with the usual rigorous tests and documentation that is required by the Pylons Project.
This demo is written using Pyramid. Note that Deform does - not depend on any particular web framework, - we just had to write a demo application in something. + not depend on any particular web framework. + We had to write a demo application in something. If you would like to run this demo application locally, please read the README file for installation of this application. diff --git a/unofficial-deformdemo/templates/main.pt b/unofficial-deformdemo/templates/main.pt index 5e11d36b..982a7c11 100644 --- a/unofficial-deformdemo/templates/main.pt +++ b/unofficial-deformdemo/templates/main.pt @@ -60,9 +60,14 @@