improve views api
Ticket
+issues
This is a bit of a holding spot for several issues with the current api:
- the current "render"-based api leaves no room for constructing pre-render objects, which will often be desirable / appropriate
- the current api (with the render vs _render distinction) requires mod developers to pay too much attention to permission checking and leaves open the possibility of too many security holes. In general we should optimize so that wagn is smart about not doing excessive permission checks (eg, repeatedly checking read permissions on the same card) and that security overrides are rare and highly visible.
- the args passing is ugly and confusing.
- we have only just begun to separate structure and context in the views. The :new and :edit views in the develop branch now show this separation, but you can't override args on a set-by-set basis, which is one of the most common needs
- It would me much more desirable to use something like "super" handling to access "all" set views rather than the _final_ stuff.
- Our use of rails' Action View stuff is pretty ugly and is possibly (?) a performance hit (for the tests if nothing else) Right now we really depend on it for all our form handling, but I'd like to revisit things to see whether we really need it or whether it's time to move on.
- The current views api doesn't produce much of a route to supporting events-like before/after functionality
+solution
View definitions:
major changes:
- no args
- considered bad form to manipulate args from within a view.
- can return string (as now), but can also return view objects
- new api class method for defining args (tentatively viewpoint)
eg:
format :html do
view :new do :perms=>:create, :tags=>:unknown_ok do |args|
frame_and_form :create do
[
view.name_fieldset.optional,
view.type_fieldset.optional,
view.content_fieldsets.optional,
view.button_fieldset.optional
]
end
end
viewpoint :new do
point.optional_help = :show
....
end
end
Implementation
The permissions handling (#2 above) is probably the most straightforward problem and should just require caching permissions checks on the format instance.
Getting rid of args should not be too hard, but there are a few considerations:
- if we continue to use cloning to create subformats, we should store args (or args equivalents) on a single attribute/object (like "point" in the example above) so that we only have to clear one thing with each subformat
- in general, args set on an inner view should not impact an outer view. so if :open calls :header calls :title, then setting a "point" in viewpoint :title should not impact the point attribute used further down in the :open view. To accomplish this, we may want each nested view to clone its args/points. (We can have a separate format-wide mechanism for cases where we do want inner views to have this power, but it should not be the standard for most arg handling.
- the api should cleanly represent when we want to override defaults vs only setting values that don't yet exist
Tentatively, I'm thinking that the view methods themselves should be defined in the set modules so that include_set_modules already sets up the hierarchy. Those methods need to be executed by the format object (so the methods would need to return proc or lambda objects).
Let's say, for example, that a Claim cardtype overrides the "new" view in ...sets/type/claim.rb
It might create something like #_html_new in the set module. The format object could call that method on its card, and retrieve a proc that it could then execute.
I'm curious as to whether we can address #5 above and make it so that "super" will trace the ancesors chain in the card's singleton class. (Haven't worked that out yet)