[Kss-devel] Registering an action.. almost...

Balazs Ree ree at ree.hu
Wed Jul 11 00:59:57 CEST 2007



2007. 07. 11, szerda keltezéssel 00.25-kor Danny Bloemendaal ezt írta:
> 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:

I told you on irc that you don't have to do this. I would do this
because I prefer to have my code in a well contained component, but
instead registering the javascript you can just use... addCommand. Try
to grep for it in the code.

> =====================================================
> <!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.

Then use kukit.cr.makeGlobalCommand instead of
kukit.cr.makeSelectorCommand.

I admit the kss registry is not much documented yet apart from the code
examples but it will be in my new book I am writing.

Otherwise you also ask lots of questions on irc that we answer one by
one in the existing docs and tutorials. I know they are far from
complete but please, take the time to go through them, they are
sometimes outdated but otherwise good and will save you a lot of time
after that.

> 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.


The main reason why we don't want to allow an arbitrary callout to js in
kss because we beleive the usage of javascript is something we want to
avoid and discourage. We provide and encourage other patterns instead.
To provide a way of working with javascript, in a way that your life
just becomes more difficult from kss, would indeed be foolish and is not
what we want.

You can register your function that does exactly this as a plugin
though, if you really believe this is what you want. It's just a few
lines and kss permits you to do that. We even had it originally, but we
decided to get rid of it. We have the experience that it is harmful and
brings us further from the original goals. But again we just talk from
our own experience which may not be the same as yours. 

> But that's another discussion ;-)

That's a discussion that has come to a conclusion already, but it is
always worth to revisit it and in some cases we can change our past
decisions (don't think this is the case here though).


-- 
Balazs Ree
-------------- next part --------------
A non-text attachment was scrubbed...
Name: not available
Type: application/pgp-signature
Size: 189 bytes
Desc: Ez az =?ISO-8859-1?Q?=FCzenetr=E9sz?=
	=?ISO-8859-1?Q?_digit=E1lis?= =?ISO-8859-1?Q?_al=E1=EDr=E1ssal?= van
	=?ISO-8859-1?Q?ell=E1tva?=
Url : http://codespeak.net/pipermail/kss-devel/attachments/20070710/fe7b94a4/attachment-0001.pgp 


More information about the Kss-devel mailing list