Ticket #1606 (assigned enhancement)

Opened 13 years ago

Last modified 13 years ago

Rethink data path from HTTP request to query

Reported by: gracinet Owned by: gracinet
Priority: P3 Milestone: CPS 3.5.7
Component: CPSDashboards Version: TRUNK
Severity: normal Keywords: filter widgets
Cc:

Description

Some queries need to be typed (dates, counters). Since the datastructure is used as a data bus between widgets, this means that datastructure values have to be typed, too. This is done by prepare() methods of filter widgets. This fits well the case where search results are displayed within a call to !CPSDocument.renderObject in 'view' mode, but doesn't work when the standard request parsing enters the process, e.g, in search results pages.

Search results pages make use of LayoutsTool.renderLayout, which calls:

  1. prepare
  2. !Datastructure.updateFromMapping()
  3. validate

The second of these steps rewrites the request string in the datastructure, therefore reverting the typing that was done during step 1.

Current ugly fix is to call prepare() within filter widgets validate() method. In particular, preparation is called twice. IIRC, the same happens within editCPSDocument.

One could envision many directions, including making proper use of the underlying schema and MappingStorageAdapter. But this has to work in the two scenarios.

Change History

comment:1 Changed 13 years ago by fguillaume

The original use of datastructure was to be a representation of the data sent by the browser, so that it could be redisplayed as is in case of errors.

Now it happens that some widgets have their prepare phase store additional data in other keys of the datastructure so that the rendering can use it. But this should be seen as a completely different use. And this data shouldn't impact validation.

comment:2 Changed 13 years ago by gracinet

Note that this applies to the very specific filter widgets implemented for CPSCourrier.

The values from datastructure will be transformed eventually in a catalog query by some other widget. This is the same kind of scenario as in Content Portlets. In the advanced search case, the datamodel refers to a transient dict that we could use it to store the typed value, thanks to the schema. In the portlet/dashboard case, the dm is linked to an object.

One solution that'd fit with the 'other key' approach would be to store the type in datastructure. Talk about reimplementing the wheel, though. The good enough solution might be to bypass LayoutsTool?.renderLayout (does not much).

comment:3 Changed 13 years ago by gracinet

  • Status changed from new to assigned
  • Milestone changed from unspecified to CPS 3.5.0

Notes for a later refactoring. It's probably not woth it to do it right now. A proper solution would be something like this:

DS should indeed hold serialized data, that's what it was meant for. Putting typed data there amounts to duplicating the validate phase. Hence the query should be taken from DM, not from DS.

On the other hand, there's the cookie stuff and update of search/filtering criteria from HTTP request in dashboards view mode, which has to stay transient. Currently this is done by the CPSCourrier.widgets.filter_widgets.RequestCookiesMixin? class in the prepare phase. This leads to lots of pollution of the widget registry (and putting the cookie id as a property on all these widgets). Both refreshs should be done by correct calls of DataStructure?.updateFromMapping. Non persistence is simply solved by not commiting the DM.

Gaining control of these updateFromMapping calls is easy In the advanced search forms implemented as Five views: don't call LayoutsTool?.renderLayout. In the dashboard/portlet use case, this requires modifying CPSDocument (new render method or behaviour of the existing one according to something in FTI). Hence the milestone.

comment:4 Changed 13 years ago by gracinet

  • Component changed from CPSCourrier to CPSDashboards

comment:5 Changed 13 years ago by fguillaume

One first error is to use the DataStructure? to provide data for a query. You should use a DataModel?.

The other horrible thing is how the cookie data is retrived by the filter widget. It should be done the same way things from the session or request are taken into account: see _updateFromSession call in FTI._computeLayoutStructure and _saveToSession/_removeFromSession a bit after. You should do something similar for cookies if it's needed.

Note: See TracTickets for help on using tickets.