WuttaWeb 0.10.1__tar.gz → 0.11.0__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/CHANGELOG.md +14 -0
  2. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/PKG-INFO +1 -1
  3. wuttaweb-0.11.0/docs/narr/index.rst +8 -0
  4. wuttaweb-0.11.0/docs/narr/templates/base.rst +251 -0
  5. wuttaweb-0.11.0/docs/narr/templates/index.rst +10 -0
  6. wuttaweb-0.11.0/docs/narr/templates/lookup.rst +69 -0
  7. wuttaweb-0.11.0/docs/narr/templates/overview.rst +15 -0
  8. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/pyproject.toml +1 -1
  9. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/forms/base.py +29 -6
  10. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/grids/base.py +26 -1
  11. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/appinfo/configure.mako +2 -2
  12. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/appinfo/index.mako +2 -2
  13. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/auth/login.mako +2 -1
  14. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/base.mako +204 -156
  15. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/base_meta.mako +1 -3
  16. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/configure.mako +2 -2
  17. wuttaweb-0.11.0/src/wuttaweb/templates/form.mako +24 -0
  18. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/grids/vue_template.mako +1 -1
  19. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/master/index.mako +9 -10
  20. wuttaweb-0.11.0/src/wuttaweb/templates/page.mako +50 -0
  21. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/forms/test_base.py +6 -0
  22. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/grids/test_base.py +6 -0
  23. wuttaweb-0.10.1/docs/narr/index.rst +0 -16
  24. wuttaweb-0.10.1/src/wuttaweb/templates/form.mako +0 -28
  25. wuttaweb-0.10.1/src/wuttaweb/templates/page.mako +0 -81
  26. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/.gitignore +0 -0
  27. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/COPYING.txt +0 -0
  28. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/README.md +0 -0
  29. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/Makefile +0 -0
  30. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/_static/.keepme +0 -0
  31. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/index.rst +0 -0
  32. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/app.rst +0 -0
  33. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/auth.rst +0 -0
  34. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/db.rst +0 -0
  35. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/forms.base.rst +0 -0
  36. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/forms.rst +0 -0
  37. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/forms.schema.rst +0 -0
  38. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/forms.widgets.rst +0 -0
  39. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/grids.base.rst +0 -0
  40. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/grids.rst +0 -0
  41. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/handler.rst +0 -0
  42. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/helpers.rst +0 -0
  43. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/index.rst +0 -0
  44. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/menus.rst +0 -0
  45. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/static.rst +0 -0
  46. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/subscribers.rst +0 -0
  47. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/util.rst +0 -0
  48. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/views.auth.rst +0 -0
  49. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/views.base.rst +0 -0
  50. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/views.common.rst +0 -0
  51. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/views.essential.rst +0 -0
  52. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/views.master.rst +0 -0
  53. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/views.people.rst +0 -0
  54. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/views.roles.rst +0 -0
  55. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/views.rst +0 -0
  56. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/views.settings.rst +0 -0
  57. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/api/wuttaweb/views.users.rst +0 -0
  58. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/conf.py +0 -0
  59. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/glossary.rst +0 -0
  60. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/index.rst +0 -0
  61. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/docs/make.bat +0 -0
  62. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/__init__.py +0 -0
  63. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/_version.py +0 -0
  64. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/app.py +0 -0
  65. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/auth.py +0 -0
  66. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/db.py +0 -0
  67. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/forms/__init__.py +0 -0
  68. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/forms/schema.py +0 -0
  69. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/forms/widgets.py +0 -0
  70. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/grids/__init__.py +0 -0
  71. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/handler.py +0 -0
  72. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/helpers.py +0 -0
  73. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/menus.py +0 -0
  74. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/static/__init__.py +0 -0
  75. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/static/img/favicon.ico +0 -0
  76. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/static/img/logo.png +0 -0
  77. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/static/img/testing.png +0 -0
  78. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/subscribers.py +0 -0
  79. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/auth/change_password.mako +0 -0
  80. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/deform/checkbox.pt +0 -0
  81. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/deform/checkbox_choice.pt +0 -0
  82. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/deform/checked_password.pt +0 -0
  83. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/deform/password.pt +0 -0
  84. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/deform/permissions.pt +0 -0
  85. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/deform/readonly/notes.pt +0 -0
  86. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/deform/readonly/objectref.pt +0 -0
  87. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/deform/readonly/permissions.pt +0 -0
  88. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/deform/select.pt +0 -0
  89. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/deform/textarea.pt +0 -0
  90. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/deform/textinput.pt +0 -0
  91. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/forbidden.mako +0 -0
  92. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/forms/vue_template.mako +0 -0
  93. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/home.mako +0 -0
  94. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/master/configure.mako +0 -0
  95. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/master/create.mako +0 -0
  96. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/master/delete.mako +0 -0
  97. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/master/edit.mako +0 -0
  98. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/master/form.mako +0 -0
  99. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/master/view.mako +0 -0
  100. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/notfound.mako +0 -0
  101. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/people/view_profile.mako +0 -0
  102. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/setup.mako +0 -0
  103. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/templates/wutta-components.mako +0 -0
  104. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/util.py +0 -0
  105. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/views/__init__.py +0 -0
  106. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/views/auth.py +0 -0
  107. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/views/base.py +0 -0
  108. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/views/common.py +0 -0
  109. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/views/essential.py +0 -0
  110. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/views/master.py +0 -0
  111. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/views/people.py +0 -0
  112. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/views/roles.py +0 -0
  113. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/views/settings.py +0 -0
  114. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/src/wuttaweb/views/users.py +0 -0
  115. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tasks.py +0 -0
  116. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/__init__.py +0 -0
  117. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/forms/__init__.py +0 -0
  118. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/forms/test_schema.py +0 -0
  119. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/forms/test_widgets.py +0 -0
  120. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/grids/__init__.py +0 -0
  121. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/libcache/bb_fontawesome_svg_core.js +0 -0
  122. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/libcache/bb_free_solid_svg_icons.js +0 -0
  123. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/libcache/bb_oruga.js +0 -0
  124. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/libcache/bb_oruga_bulma.css +0 -0
  125. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/libcache/bb_oruga_bulma.js +0 -0
  126. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/libcache/bb_vue.js +0 -0
  127. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/libcache/bb_vue_fontawesome.js +0 -0
  128. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/libcache/buefy.css +0 -0
  129. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/libcache/buefy.js +0 -0
  130. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/libcache/fontawesome.js +0 -0
  131. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/libcache/vue.js +0 -0
  132. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/libcache/vue_resource.js +0 -0
  133. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/test_app.py +0 -0
  134. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/test_auth.py +0 -0
  135. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/test_handler.py +0 -0
  136. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/test_helpers.py +0 -0
  137. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/test_menus.py +0 -0
  138. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/test_static.py +0 -0
  139. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/test_subscribers.py +0 -0
  140. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/test_util.py +0 -0
  141. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/util.py +0 -0
  142. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/views/__init__.py +0 -0
  143. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/views/test___init__.py +0 -0
  144. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/views/test_auth.py +0 -0
  145. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/views/test_base.py +0 -0
  146. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/views/test_common.py +0 -0
  147. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/views/test_master.py +0 -0
  148. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/views/test_people.py +0 -0
  149. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/views/test_roles.py +0 -0
  150. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/views/test_settings.py +0 -0
  151. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tests/views/test_users.py +0 -0
  152. {wuttaweb-0.10.1 → wuttaweb-0.11.0}/tox.ini +0 -0
@@ -5,6 +5,20 @@ All notable changes to wuttaweb will be documented in this file.
5
5
  The format is based on [Keep a Changelog](http://keepachangelog.com/en/1.0.0/)
6
6
  and this project adheres to [Semantic Versioning](http://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## v0.11.0 (2024-08-20)
9
+
10
+ ### Feat
11
+
12
+ - split up base templates into more sections (def blocks)
13
+ - simplify base/page/form template structure; add docs
14
+
15
+ ## v0.10.2 (2024-08-19)
16
+
17
+ ### Fix
18
+
19
+ - add `render_vue_finalize()` methods for grids, forms
20
+ - avoid error when checking model for column property
21
+
8
22
  ## v0.10.1 (2024-08-19)
9
23
 
10
24
  ### Fix
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: WuttaWeb
3
- Version: 0.10.1
3
+ Version: 0.11.0
4
4
  Summary: Web App for Wutta Framework
5
5
  Project-URL: Homepage, https://wuttaproject.org/
6
6
  Project-URL: Repository, https://forgejo.wuttaproject.org/wutta/wuttaweb
@@ -0,0 +1,8 @@
1
+
2
+ Documentation
3
+ =============
4
+
5
+ .. toctree::
6
+ :maxdepth: 2
7
+
8
+ templates/index
@@ -0,0 +1,251 @@
1
+
2
+ Base Templates
3
+ ==============
4
+
5
+ This describes the base templates. When creating a custom page
6
+ template, you most often need to inherit from one of these:
7
+
8
+ * :ref:`page_base_template`
9
+ * :ref:`form_base_template`
10
+ * :ref:`master_base_templates`
11
+
12
+ .. note::
13
+
14
+ Any of these templates may be overridden; see
15
+ :ref:`mako-template-override`.
16
+
17
+
18
+ Global Base
19
+ ~~~~~~~~~~~
20
+
21
+ There is exactly one "true base template" for the web app, designated
22
+ as: ``/base.mako``
23
+
24
+ The default base template is ``wuttaweb:templates/base.mako`` and all
25
+ page templates inherit from it. However they inherit it by *name*
26
+ only (``/base.mako``) - therefore if you override this via custom
27
+ template search paths, effectively you have changed the **theme**.
28
+
29
+ In addition to general layout/structure, this template is reponsible
30
+ for creating the Vue app which encompasses the whole of every page.
31
+ It also establishes the ``WholePage`` component which is the Vue app's
32
+ one and only child component.
33
+
34
+ (``WholePage`` in turn will have other children, for page content.)
35
+
36
+ There is usually no need to define a template which inherits directly
37
+ from ``/base.mako``, rather you should inherit from ``/page.mako``
38
+ (see next section) or similar.
39
+
40
+ As pertains to Vue component logic, there are 3 blocks which you may
41
+ find a need to override. These are defined by ``/base.mako`` so will
42
+ apply to *all* templates:
43
+
44
+ * ``render_vue_templates()``
45
+ * ``modify_vue_vars()``
46
+ * ``make_vue_components()``
47
+
48
+ Most often it is necessary to customize ``modify_vue_vars()`` but keep
49
+ reading for an example.
50
+
51
+
52
+ .. _page_base_template:
53
+
54
+ Page Base
55
+ ~~~~~~~~~
56
+
57
+ The common base template for pages, designated as: ``/page.mako``
58
+
59
+ This extends the Vue logic from ``/base.mako`` by establishing
60
+ ``ThisPage`` component, which wraps all content within the current
61
+ page.
62
+
63
+ The final structure then is conceptually like:
64
+
65
+ .. code-block:: html
66
+
67
+ <div id="app">
68
+ <whole-page>
69
+ <!-- menu etc. -->
70
+ <this-page>
71
+ <!-- page contents -->
72
+ </this-page>
73
+ </whole-page>
74
+ </div>
75
+
76
+ Simple usage is to create a template which inherits from
77
+ ``/page.mako`` and defines a ``page_content()`` block, e.g.:
78
+
79
+ .. code-block:: mako
80
+
81
+ <%inherit file="/page.mako" />
82
+
83
+ <%def name="page_content()">
84
+ <p>hello world!</p>
85
+ </%def>
86
+
87
+ The default ``/page.mako`` logic knows where to render the
88
+ ``page_content()`` block so that it fits properly into the
89
+ component/layout structure.
90
+
91
+ Often you may need to customize Vue component logic for a page; this
92
+ is done by defining one of the blocks mentioned in previous section.
93
+
94
+ Here is a simple example which shows how this works:
95
+
96
+ .. code-block:: mako
97
+
98
+ <%inherit file="/page.mako" />
99
+
100
+ <%def name="page_content()">
101
+ <b-field label="Foo">
102
+ <b-input v-model="foo" />
103
+ </b-field>
104
+ <b-field>
105
+ <b-button @click="alertFoo()">
106
+ Alert
107
+ </b-button>
108
+ </b-field>
109
+ </%def>
110
+
111
+ <%def name="modify_vue_vars()">
112
+ ${parent.modify_vue_vars()}
113
+ <script>
114
+
115
+ // nb. this becomes ThisPage.data.foo
116
+ ThisPageData.foo = 'bar'
117
+
118
+ ThisPage.methods.alertFoo = function() {
119
+ alert("value of foo is: " + this.foo)
120
+ }
121
+
122
+ </script>
123
+ </%def>
124
+
125
+ You can see that ``page_content()`` is able to reference things from
126
+ ``ThisPage`` component, while the ``modify_vue_vars()`` block is used
127
+ to define those same things on the component.
128
+
129
+
130
+ .. _form_base_template:
131
+
132
+ Form Base
133
+ ~~~~~~~~~
134
+
135
+ The common base template for pages with a form, designated as:
136
+ ``/form.mako``
137
+
138
+ This expects the context dict to contain ``'form'`` which points to a
139
+ :class:`~wuttaweb.forms.base.Form` instance.
140
+
141
+ This template extends the Vue logic from ``/page.mako`` by
142
+ establishing a Vue component specific to the form object.
143
+
144
+ The final structure then is conceptually like:
145
+
146
+ .. code-block:: html
147
+
148
+ <div id="app">
149
+ <whole-page>
150
+ <!-- menu etc. -->
151
+ <this-page>
152
+ <wutta-form>
153
+ <!-- fields etc. -->
154
+ </wutta-form>
155
+ </this-page>
156
+ </whole-page>
157
+ </div>
158
+
159
+ A simple example which assumes one of the form fields exposes a button
160
+ with click event that triggers ``alertFoo()`` method on the form
161
+ component:
162
+
163
+ .. code-block:: mako
164
+
165
+ <%inherit file="/form.mako" />
166
+
167
+ <%def name="modify_vue_vars()">
168
+ ${parent.modify_vue_vars()}
169
+ <script>
170
+
171
+ // nb. this becomes e.g. WuttaForm.foo when component is created
172
+ ${form.vue_component}Data.foo = 'bar'
173
+
174
+ ${form.vue_component}.methods.alertFoo = function() {
175
+ alert("value of foo is: " + this.foo)
176
+ }
177
+
178
+ </script>
179
+ </%def>
180
+
181
+ .. note::
182
+
183
+ By default, ``${form.vue_compoment}`` is rendered as ``WuttaForm``
184
+ but that is not guaranteed. You should resist the temptation to
185
+ hard-code that; always use ``${form.vue_component}`` and (where
186
+ applicable) ``${form.vue_tagname}``.
187
+
188
+ The reason for this is to allow multiple forms to exist on a single
189
+ page, each with a separate Vue component. (Which is not shown in
190
+ the above example.)
191
+
192
+ See also :attr:`~wuttaweb.forms.base.Form.vue_component` and
193
+ :attr:`~wuttaweb.forms.base.Form.vue_tagname`.
194
+
195
+
196
+ .. _master_base_templates:
197
+
198
+ Master Base
199
+ ~~~~~~~~~~~
200
+
201
+ These templates are for use with
202
+ :class:`~wuttaweb.views.master.MasterView`. Each is the default
203
+ template used for the corresponding route/view, unless a more specific
204
+ template is defined.
205
+
206
+ The "index" template is unique in that it is (usually) for listing the
207
+ model data:
208
+
209
+ * ``/master/index.mako``
210
+
211
+ The "form" template is just a base template, does not directly
212
+ correspond to a route/view. Other CRUD templates inherit from it.
213
+ This inherits from ``/form.mako`` (see previous section).
214
+
215
+ * ``/master/form.mako``
216
+
217
+ These CRUD templates inherit from ``/master/form.mako`` and so
218
+ require a ``'form'`` in the context dict.
219
+
220
+ * ``/master/create.mako``
221
+ * ``/master/view.mako``
222
+ * ``/master/edit.mako``
223
+ * ``/master/delete.mako``
224
+
225
+ The "configure" template is for master views which have a
226
+ configuration page.
227
+
228
+ * ``/master/configure.mako``
229
+
230
+ Usage for these is not significantly different from the ones shown
231
+ above, in cases where you actually need to override the template.
232
+
233
+ As an example let's say you have defined a ``WidgetMasterView`` class
234
+ and want to override its "view" template. You would then create a
235
+ file as ``/widgets/view.mako`` (within your templates folder) and
236
+ be sure to inherit from the correct base template:
237
+
238
+ .. code-block:: mako
239
+
240
+ <%inherit file="/master/view.mako" />
241
+
242
+ <%def name="page_content()">
243
+
244
+ <p>THIS APPEARS FIRST!</p>
245
+
246
+ ## nb. the form will appear here
247
+ ${parent.page_content()}
248
+
249
+ <p>MADE IT TO THE END!</p>
250
+
251
+ </%def>
@@ -0,0 +1,10 @@
1
+
2
+ Templates
3
+ =========
4
+
5
+ .. toctree::
6
+ :maxdepth: 2
7
+
8
+ overview
9
+ base
10
+ lookup
@@ -0,0 +1,69 @@
1
+
2
+ Template Lookup
3
+ ===============
4
+
5
+ The discovery of templates is handled by Mako, and is configurable.
6
+
7
+ WuttaWeb comes with all templates it needs, in the path designated as
8
+ ``wuttaweb:templates``.
9
+
10
+ When the app renders a page, it invokes the Mako lookup logic, which
11
+ searches one or more folders and returns the first matching file it
12
+ encounters. By default ``wuttaweb:templates`` is the only place it
13
+ looks.
14
+
15
+ A template is searched for by "name" but it is more path-like, e.g.
16
+ ``/page.mako`` or ``/master/index.mako`` etc. So for example the file
17
+ at ``wuttaweb:templates/home.mako`` is used for home page (using
18
+ lookup name ``/home.mako``) by default.
19
+
20
+
21
+ .. _mako-template-override:
22
+
23
+ Overriding the Search Paths
24
+ ~~~~~~~~~~~~~~~~~~~~~~~~~~~
25
+
26
+ The basic idea is to give it a list of paths it should search when
27
+ trying to find a template. The first template file found for a given
28
+ search name is used and no further search is done for that name.
29
+
30
+ You can define the Mako lookup sequence in your ``web.conf`` as
31
+ follows:
32
+
33
+ .. code-block:: ini
34
+
35
+ [app:main]
36
+ mako.directories =
37
+ /random/path/on/disk
38
+ poser.web:templates
39
+ wuttaweb:templates
40
+
41
+ This setting is interpreted by ``pyramid_mako`` (`docs`_).
42
+
43
+ .. _docs: https://docs.pylonsproject.org/projects/pyramid_mako/en/latest/index.html#mako-directories
44
+
45
+ Here ``wuttaweb:templates/home.mako`` would still be used by default
46
+ for home page, *unless* e.g. ``/random/path/on/disk/home.mako``
47
+ existed in which case that would be used.
48
+
49
+ Each path can have an arbitrary set of templates, they will
50
+ effectively be combined to a single set by the app, with the
51
+ definition order determining search priority.
52
+
53
+ If you are already using a custom ``app.main()`` function for
54
+ constructing the web app during startup, it may be a good idea to
55
+ change the *default* search paths to include your package.
56
+
57
+ Setup for custom ``app.main()`` is beyond the scope here, but assuming
58
+ you *do* already have one, this is what it looks like::
59
+
60
+ from wuttaweb import app as base
61
+
62
+ def main(global_config, **settings):
63
+
64
+ # nb. set the *default* mako search paths; however config can
65
+ # still override with method shown above
66
+ settings.setdefault('mako.directories', ['poser.web:templates',
67
+ 'wuttaweb:templates'])
68
+
69
+ return base.main(global_config, **settings)
@@ -0,0 +1,15 @@
1
+
2
+ Overview
3
+ ========
4
+
5
+ WuttaWeb uses the `Mako`_ template language for page rendering.
6
+
7
+ .. _Mako: https://www.makotemplates.org/
8
+
9
+ There is a "global" base template which effectively defines the
10
+ "theme" (page layout, Vue component structure). A few other base
11
+ templates provide a starting point for any custom pages; see
12
+ :doc:`base`.
13
+
14
+ Templates are found via lookup which is handled by Mako. This is
15
+ configurable so you can override any or all; see :doc:`lookup`.
@@ -6,7 +6,7 @@ build-backend = "hatchling.build"
6
6
 
7
7
  [project]
8
8
  name = "WuttaWeb"
9
- version = "0.10.1"
9
+ version = "0.11.0"
10
10
  description = "Web App for Wutta Framework"
11
11
  readme = "README.md"
12
12
  authors = [{name = "Lance Edgar", email = "lance@edbob.org"}]
@@ -918,19 +918,42 @@ class Form:
918
918
 
919
919
  return HTML.tag('b-field', c=[html], **attrs)
920
920
 
921
+ def render_vue_finalize(self):
922
+ """
923
+ Render the Vue "finalize" script for the form.
924
+
925
+ By default this simply returns:
926
+
927
+ .. code-block:: html
928
+
929
+ <script>
930
+ WuttaForm.data = function() { return WuttaFormData }
931
+ Vue.component('wutta-form', WuttaForm)
932
+ </script>
933
+
934
+ The actual output may depend on various form attributes, in
935
+ particular :attr:`vue_tagname`.
936
+ """
937
+ set_data = f"{self.vue_component}.data = function() {{ return {self.vue_component}Data }}"
938
+ make_component = f"Vue.component('{self.vue_tagname}', {self.vue_component})"
939
+ return HTML.tag('script', c=['\n',
940
+ HTML.literal(set_data),
941
+ '\n',
942
+ HTML.literal(make_component),
943
+ '\n'])
944
+
921
945
  def get_vue_model_data(self):
922
946
  """
923
947
  Returns a dict with form model data. Values may be nested
924
948
  depending on the types of fields contained in the form.
925
949
 
926
- Note that the values need not be "converted" (to be
927
- JSON-compatible) at this stage, for instance ``colander.null``
928
- is not a problem here. The point is to collect the raw data.
950
+ This collects the ``cstruct`` values for all fields which are
951
+ present both in :attr:`fields` as well as the Deform schema.
929
952
 
930
- The dict should have a key/value for each field in the form.
953
+ It also converts each as needed, to ensure it is
954
+ JSON-serializable.
931
955
 
932
- This method is called by :meth:`render_vue_model_data()` which
933
- is responsible for ensuring JSON compatibility.
956
+ :returns: Dict of field/value items.
934
957
  """
935
958
  dform = self.get_deform()
936
959
  model_data = {}
@@ -578,7 +578,8 @@ class Grid:
578
578
  if key in sorters:
579
579
  continue
580
580
  prop = getattr(self.model_class, key, None)
581
- if prop and isinstance(prop.property, orm.ColumnProperty):
581
+ if (prop and hasattr(prop, 'property')
582
+ and isinstance(prop.property, orm.ColumnProperty)):
582
583
  sorters[prop.key] = self.make_sorter(prop)
583
584
 
584
585
  return sorters
@@ -1277,6 +1278,30 @@ class Grid:
1277
1278
  output = render(template, context)
1278
1279
  return HTML.literal(output)
1279
1280
 
1281
+ def render_vue_finalize(self):
1282
+ """
1283
+ Render the Vue "finalize" script for the grid.
1284
+
1285
+ By default this simply returns:
1286
+
1287
+ .. code-block:: html
1288
+
1289
+ <script>
1290
+ WuttaGrid.data = function() { return WuttaGridData }
1291
+ Vue.component('wutta-grid', WuttaGrid)
1292
+ </script>
1293
+
1294
+ The actual output may depend on various grid attributes, in
1295
+ particular :attr:`vue_tagname`.
1296
+ """
1297
+ set_data = f"{self.vue_component}.data = function() {{ return {self.vue_component}Data }}"
1298
+ make_component = f"Vue.component('{self.vue_tagname}', {self.vue_component})"
1299
+ return HTML.tag('script', c=['\n',
1300
+ HTML.literal(set_data),
1301
+ '\n',
1302
+ HTML.literal(make_component),
1303
+ '\n'])
1304
+
1280
1305
  def get_vue_columns(self):
1281
1306
  """
1282
1307
  Returns a list of Vue-compatible column definitions.
@@ -140,8 +140,8 @@
140
140
  </div>
141
141
  </%def>
142
142
 
143
- <%def name="modify_this_page_vars()">
144
- ${parent.modify_this_page_vars()}
143
+ <%def name="modify_vue_vars()">
144
+ ${parent.modify_vue_vars()}
145
145
  <script>
146
146
 
147
147
  ThisPageData.weblibs = ${json.dumps(weblibs or [])|n}
@@ -48,8 +48,8 @@
48
48
 
49
49
  </%def>
50
50
 
51
- <%def name="modify_this_page_vars()">
52
- ${parent.modify_this_page_vars()}
51
+ <%def name="modify_vue_vars()">
52
+ ${parent.modify_vue_vars()}
53
53
  <script>
54
54
  ThisPageData.configFiles = ${json.dumps([dict(path=p, priority=i) for i, p in enumerate(config.get_prioritized_files(), 1)])|n}
55
55
  </script>
@@ -19,7 +19,8 @@
19
19
  </div>
20
20
  </%def>
21
21
 
22
- <%def name="modify_this_page_vars()">
22
+ <%def name="modify_vue_vars()">
23
+ ${parent.modify_vue_vars()}
23
24
  <script>
24
25
 
25
26
  ${form.vue_component}Data.usernameInput = null