[Kss-devel] Registering an action.. almost...
Danny Bloemendaal
danny.bloemendaal at informaat.nl
Wed Jul 11 00:25:41 CEST 2007
Today I have been struggling in order to have a custom action work
from the server. With not much success so far.
This is what I did:
In my product I created the file interfaces.py:
========================================================
interfaces.py
========================================================
from zope.interface import Interface
class IICEKSSCommands(Interface):
"""The commands"""
def initializePortlets():
"""Make portlets draggable and collapsable"""
========================================================
And I created a commands.py:
========================================================
commands.py
========================================================
try:
from azax.selectors import Selector, CssSelector,
HtmlIdSelector, SameNodeSelector
from azax.azaxview import AzaxViewAdapter
from azax.deprecated import deprecated, deprecated_warning
from azax.parsers import XmlParser, HtmlParser
_dummy = Selector, CssSelector, HtmlIdSelector,
SameNodeSelector, AzaxViewAdapter, deprecated, deprecated_warning,
XmlParser, HtmlParser # satisfy pyflakes
except ImportError:
from Products.azax.selectors import Selector, CssSelector,
HtmlIdSelector, SameNodeSelector
from Products.azax.azaxview import AzaxViewAdapter
from Products.azax.deprecated import deprecated, deprecated_warning
from Products.azax.parsers import XmlParser, HtmlParser
class ICEKSSCommands(AzaxViewAdapter):
__allow_access_to_unprotected_subobjects__ = 1
def initializePortlets(self):
""" see interfaces.py """
command = self.commands.addCommand('initializePortlets')
=========================================================
and finally in my configure.zcml:
========================================================
configure.zcml
========================================================
<configure xmlns="http://namespaces.zope.org/zope"
xmlns:browser="http://namespaces.zope.org/browser"
xmlns:five="http://namespaces.zope.org/five"
xmlns:azax="http://namespaces.zope.org/azax"
xmlns:zcml="http://namespaces.zope.org/zcml"
>
<configure zcml:condition="have compat_five">
<adapter
for="Products.azax.interfaces.IAzaxView"
provides=".interfaces.IICEKSSCommands"
factory=".commands.ICEKSSCommands"
/>
</configure>
<configure zcml:condition="have compat_not_five">
<adapter
for="azax.interfaces.IAzaxView"
provides=".interfaces.IICEKSSCommands"
factory=".commands.ICEKSSCommands"
/>
</configure>
<azax:registerAction
name="initializePortlets"
command_factory="global"
/>
</configure>
======================================================
Then, I have this javascript file that's always included and in there
I did this:
======================================================
portletmanager.js
======================================================
kukit.actionsGlobalRegistry.register("initializePortlets", function
(oper) {
oper.completeParms([], {}, "initializePortlets");
PortletManager.initialize();
}
)
kukit.commandsGlobalRegistry.registerFromAction('initializePortlets',
kukit.cr.makeSelectorCommand);
=======================================================
In here, PortletManager is an object that's already loaded. It needs
to be reinitialized after certain ajax calls.
And finally, I have a view that deals with ajax calls:
=====================================================
trackerView.py
=====================================================
try:
from azax import AzaxBaseView, force_unicode
from azax.plugins.core.interfaces import IKSSCoreCommands
from azax.plugins.effects.interfaces import
IScriptaculousEffectsCommands
except ImportError:
from Products.azax import AzaxBaseView, force_unicode
from Products.azax.plugins.core.interfaces import IKSSCoreCommands
from Products.azax.plugins.effects.interfaces import
IScriptaculousEffectsCommands
from Products.ICETools.interfaces import IICEKSSCommands
import datetime, time
from Products.CMFCore.utils import getToolByName
from zope.app.pagetemplate.viewpagetemplatefile import
ViewPageTemplateFile
class TrackerView(AzaxBaseView):
.....
def myMethod(self):
.....
# return a new portlet
IKSSCoreCommands(self).replaceHTML('#portlet-issues', result)
# make sure that after it's inserted, the PortletManager can
reinitialize.
IICEKSSCommands(self).initializePortlets()
return self.render()
======================================================
So, ok.. all this work only to just be able to call on tiny
javascript function... ok.. what has to be done, has to be done. So,
after restarting the whole bunch and doing some interaction after
which this last method is called, I get this back from the server
after the request:
=====================================================
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional
.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
xmlns:kukit="http://www.kukit.org/commands/1.0"><body>
<kukit:commands>
<kukit:command selector="#portlet-issues" name="replaceHTML"
selectorType="">
<kukit:param name="html">
<dl class="portlet" id="portlet-issues"> < ... cut ...></dl>
</kukit:param>
</kukit:command>
<kukit:command name="initializePortlets">
</kukit:command>
</kukit:commands>
</body></html>
=========================================================
That part looks good.. however, my function isn't called. Kukit reports:
===============================
Number of commands: 2
Selector type: default (css), selector : "#portlet-issues", selected
nodes:1+
Command Name: replaceHTML
Selector type: default (css), selector : "null", selected nodes:0
Selector found no nodes
=================================
Now, obviously I'm doing something wrong although I feel I'm close.
I'm not sure why it tries to find nodes because my function is a
global one that doesn't operate on any node.
This action does work in a kss file though using action-
client:initializePortlets.
So, anybody, please shed some light on this. I'm stuck.
Danny.
PS: I still don't like this enormously overcomplicated way of doing
one simple thing. Maybe, after this works I will create a generic
javascript action that can have any javascript function as a
parameter and evals that.
I just want to do things like:
{
action-client: callFunction;
callFunction-name:myJsFunction;
callFunction-parameters:params(a, b, c);
}
And I understand that this may not be clean and different from the
patterns but I'm just a simple kss end user who needs to get his work
done with it.
But that's another discussion ;-)
More information about the Kss-devel
mailing list