[ckan-dev] IDataSetForm.setup_template_variables vs. IPackageController.before_view

Haq, Salman Salman.Haq at neustar.biz
Wed Jun 6 14:29:27 UTC 2012



On 6/6/12 5:29 AM, "Sean Hammond" <sean.hammond at okfn.org> wrote:

>> It seems that either function can be used to modify 'pkg_dict' which
>> is then passed to the templates to customize what is rendered.
>> 
>> Which ones should be used and when?
>
>You can use your extension to test exactly when each function does and
>does not get called, but:
>
>It looks like setup_template_variables() is only called in a couple of
>places, when creating a new dataset and when editing a dataset (which
>makes sense as it's part of the IDatasetForm plugin which only gets used
>when there's a form involved). I'm not familiar with this function, but
>looking at the core extensions in ckan/ckanext, the method is used by
>the organizations extension to implement its custom dataset create/edit
>forms.
>
>before_view() is called whenever a package is dictized, including on the
>package read page and (I think) also on package list pages (e.g.
>dataset search results listings). But note that before_view() does not
>get called when accessing CKAN via the API, only when via the web UI.
>The purpose of before_view() is to allow extensions to modify the
>package dict before anything gets displayed to the user. For example, it
>is used by the multilingual extension to translate dataset fields like
>title, description, etc. into the user's selected language before
>displaying them.
>
>Hope that helps

Thank you for the detailed reply.

Consider the following use case:
Retrieve a statistic and display it on each page with the URL prefix
/dataset/{pkg_id}/. That is to say, on *each* of the dataset pages
accessible by the minor navigation items: 'View', 'Resources', 'Related',
'History', 'Settings', and 'Authorization'. The catch is that this
statistic is not part of 'pkg_dict' as returned by
model_dictize.package_dictize and has to be retrieved by special logic in
an extension. Assume layout.html has been overridden appropriately by this
extension, so it's a question of retrieving and passing the right data to
the template. Now suppose that said extension defines a plugin that
implements IPackageController and IDatasetForm interfaces. Turns out that
this is quite tricky.

Consider the callbacks that will occur when clicking on each of the minor
navigation items:

[View] - IPackageController.before_view, IPackageController.read
[Resources/Add Edit Resource] - IPackageController.read,
IDatasetForm.setup_template_variables
[Resources/<resource>] - IPackageController.read
[Related] - IPackageController.before_view, IPackageController.read
[History] - IPackageController.read
[Settings] - IPackageController.before_view, IPackageController.read
[Authorization] - IPackageController.read

There are several problems here:
 - Two methods can modify template context: IPackageController.before_view
(indirectly, via pkg_dict) and IDatasetForm.setup_template_variables
(directly).
 - It's not obvious which is called when.
 - They are not called for all menu items.
 - The only method that is called back every time is IPackageControll.read
but it CANNOT modify the template context directly or indirectly.

Generally speaking, an extension cannot reliably extend the concept of a
dataset because it is not always possible to retrieve and display
extension-specific data.

I would recommend changing the signature of the IPackageController.read
callback so it can modify the pkg_dict. However there are other approaches
to fixing the issue and I'd like to hear what other developers have to say.

Thanks,
Salman






More information about the ckan-dev mailing list