Author: bree Date: Sun Apr 9 18:44:12 2006 New Revision: 2798 Added: azax/branches/plugin/commands.py azax/branches/plugin/parsers.py azax/branches/plugin/selectors.py Modified: azax/branches/plugin/azaxview.py azax/branches/plugin/browser/kukitresponse.pt azax/branches/plugin/configure.zcml azax/branches/plugin/interfaces.py azax/branches/plugin/tests/test_azaxview.py Log: Refactoring. Rendering command via adapter hook, + break up files
Modified: azax/branches/plugin/azaxview.py ============================================================================== --- azax/branches/plugin/azaxview.py (original) +++ azax/branches/plugin/azaxview.py Sun Apr 9 18:44:12 2006 @@ -19,139 +19,25 @@ # Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA # 02111-1307, USA. # +'''\ +AZAX Base view class -from zope.interface import implements -from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile -from Products.Five import BrowserView -from unicode_quirks import force_unicode -from plugins import Command - -import htmlentitydefs -import re -_entity_regexp = re.compile(r"&([a-zA-Z]+);") - -# -- -# Parser implementations -# -# These assure that output is valid XML or HTML and fix the code or -# raise an exception. -# -# The wrapping makes it possible to change the parser transparently -# if necessary. -# -- - -class XmlParser(object): - '''Custom XML parser - - wraps the parser implementation - ''' - - from BeautifulSoup import BeautifulStoneSoup - - def __init__(self, value): - value = force_unicode(value) - self.soup = self.BeautifulStoneSoup(value) - - def __call__(self): - return unicode(self.soup) - -class HtmlParser(object): - '''Custom HTML parser +All the implementations should create a specialization +of this class when building their browser views. - wraps the parser implementation - ''' +The policy is that a method should build up a command +set on available methods and then return self.render(). - from BeautifulSoup import BeautifulSoup - - def __init__(self, value): - value = force_unicode(value) - self.soup = self.BeautifulSoup(value) - for tag in self.soup.fetch(recursive=False): - tag['xmlns'] = "http://www.w3.org/1999/xhtml" - - def __call__(self): - return unicode(self.soup) - -# -- -# Marshal objects -# -# These build up the response and get marshalled to the client -# in the defined format -# -- +The default command set is implemented in the base class +as well. +''' -class AzaxParam: - - def __init__(self, name, content=''): - self.name = name - # Content must be str with ascii encoding, or unicode! - self.content = force_unicode(content) - - def getName(self): - return self.name - - def getContent(self): - return self.content - -class AzaxCommand: - - def __init__(self, name, selector): - Command.checkRegistered(name) - if isinstance(selector, basestring): - self.selector = selector - self.selectorType = '' - else: - self.selector = selector.value - self.selectorType = selector.type - self.name = name - self.params = [] - - def addParam(self, name, content=''): - param = AzaxParam(name, content) - self.params.append(param) - return param - - def getName(self): - return self.name - - def getSelector(self): - return self.selector - - def getSelectorType(self): - return self.selectorType - - def getParams(self): - return self.params - -XPATH_SELECTOR = 'xpath' -CSS_SELECTOR = 'css' -HTMLID_SELECTOR = 'htmlid' - -class XpathSelector: - - type = XPATH_SELECTOR - - def __init__(self, selector): - self.value = selector - -class CssSelector: - - type = CSS_SELECTOR - - def __init__(self, selector): - self.value = selector - -class HtmlIdSelector: - - type = HTMLID_SELECTOR - - def __init__(self, selector): - self.value = selector -# -- -# Base view class -# -# All the implementations should create a specialization -# of this class when building their browser views -# -- +from Products.Five import BrowserView +from commands import AzaxCommands, AzaxCommand +from selectors import XpathSelector, CssSelector, HtmlIdSelector +from parsers import XmlParser, HtmlParser +import zope.component +from zope.interface import Interface class AzaxBaseView(BrowserView): """ Base azax view @@ -160,25 +46,15 @@ generate it out. """ - # XML output gets rendered via a page template - _render = ViewPageTemplateFile('browser/kukitresponse.pt', content_type='text/xml;charset=utf-8') - - # replace named entities to fix a bug in IE def render(self): - name2codepoint = htmlentitydefs.name2codepoint - def entity_replacer(m): - value = name2codepoint.get(m.group(1)) - if value is None: - return m.group(0) - return "&#%i;" % value - - result = self._render() - result = _entity_regexp.sub(entity_replacer, result) - return result + '''All methods must use this to return their command set + ''' + adapter = zope.component.getMultiAdapter((self.getCommands(), self.request), Interface, 'render') + return adapter.render() def __init__(self, context, request): BrowserView.__init__(self, context, request) - self.commands = [] + self.commands = AzaxCommands() def addCommand(self, name, selector): command = AzaxCommand(name, selector) @@ -187,19 +63,18 @@ def getCommands(self): return self.commands - def getXpathSelector(self, selector): - return XpathSelector(selector) + return XpathSelector(selector) def getCssSelector(self, selector): - return CssSelector(selector) + return CssSelector(selector) def getHtmlIdSelector(self, selector): - return HtmlIdSelector(selector) + return HtmlIdSelector(selector) # -- - # commands + # default set of commands # -- def setHtmlAsChild(self, selector, new_value): Modified: azax/branches/plugin/browser/kukitresponse.pt ============================================================================== --- azax/branches/plugin/browser/kukitresponse.pt (original) +++ azax/branches/plugin/browser/kukitresponse.pt Sun Apr 9 18:44:12 2006 @@ -4,7 +4,7 @@ xmlns:tal="http://xml.zope.org/namespaces/tal" xmlns:metal="http://xml.zope.org/namespaces/metal" xmlns:i18n="http://xml.zope.org/namespaces/i18n"><body> -<kukit:command tal:repeat="command view/getCommands" +<kukit:command tal:repeat="command context" selector="div#demo" name="setHtmlAsChild" selectorType="" tal:attributes="selector command/getSelector; Added: azax/branches/plugin/commands.py ============================================================================== --- (empty file) +++ azax/branches/plugin/commands.py Sun Apr 9 18:44:12 2006 @@ -0,0 +1,108 @@ +# -*- coding: ISO-8859-15 -*- +# Copyright (c) 2006 +# Authors: +# Godefroid Chapelle <[EMAIL PROTECTED]> +# Bal�zs Re� <[EMAIL PROTECTED]> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. +# +'''\ +Marshal objects + +These build up the response and get marshalled to the client +in the defined format +''' + +from zope.interface import implements +from zope.app.pagetemplate.viewpagetemplatefile import ViewPageTemplateFile +from interfaces import IAzaxCommands +from plugins import Command +from unicode_quirks import force_unicode +import re, htmlentitydefs + +class AzaxCommands(list): + implements(IAzaxCommands) + +class AzaxParam: + + def __init__(self, name, content=''): + self.name = name + # Content must be str with ascii encoding, or unicode! + self.content = force_unicode(content) + + def getName(self): + return self.name + + def getContent(self): + return self.content + +class AzaxCommand: + + def __init__(self, name, selector): + Command.checkRegistered(name) + if isinstance(selector, basestring): + self.selector = selector + self.selectorType = '' + else: + self.selector = selector.value + self.selectorType = selector.type + self.name = name + self.params = [] + + def addParam(self, name, content=''): + param = AzaxParam(name, content) + self.params.append(param) + return param + + def getName(self): + return self.name + + def getSelector(self): + return self.selector + + def getSelectorType(self): + return self.selectorType + + def getParams(self): + return self.params + +class CommandView(object): + '''View of a command. + + The render method does actual marshalling + of the commands to be sent to the client. + ''' + + _entity_regexp = re.compile(r"&([a-zA-Z]+);") + + def __init__(self, context, request): + self.context = context + self.request = request + + # XML output gets rendered via a page template + _render = ViewPageTemplateFile('browser/kukitresponse.pt', content_type='text/xml;charset=utf-8') + + # replace named entities to fix a bug in IE + def render(self): + name2codepoint = htmlentitydefs.name2codepoint + def entity_replacer(m): + value = name2codepoint.get(m.group(1)) + if value is None: + return m.group(0) + return "&#%i;" % value + + result = self._render() + result = self._entity_regexp.sub(entity_replacer, result) + return result Modified: azax/branches/plugin/configure.zcml ============================================================================== --- azax/branches/plugin/configure.zcml (original) +++ azax/branches/plugin/configure.zcml Sun Apr 9 18:44:12 2006 @@ -64,4 +64,12 @@ name="testAzaxStyleParse.js" /> + <adapter + for=".interfaces.IAzaxCommands + zope.publisher.interfaces.browser.IBrowserRequest" + provides="zope.interface.Interface" + factory=".commands.CommandView" + name="render" + /> + </configure> Modified: azax/branches/plugin/interfaces.py ============================================================================== --- azax/branches/plugin/interfaces.py (original) +++ azax/branches/plugin/interfaces.py Sun Apr 9 18:44:12 2006 @@ -21,3 +21,5 @@ from zope.interface import Interface +class IAzaxCommands(Interface): + 'Azax commands' Added: azax/branches/plugin/parsers.py ============================================================================== --- (empty file) +++ azax/branches/plugin/parsers.py Sun Apr 9 18:44:12 2006 @@ -0,0 +1,63 @@ +# -*- coding: ISO-8859-15 -*- +# Copyright (c) 2006 +# Authors: +# Godefroid Chapelle <[EMAIL PROTECTED]> +# Bal�zs Re� <[EMAIL PROTECTED]> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. +# +'''\ +Parser implementations + +These assure that output is valid XML or HTML and fix the code or +raise an exception. + +The wrapping makes it possible to change the parser transparently +if necessary. +''' + +from unicode_quirks import force_unicode + +class XmlParser(object): + '''Custom XML parser + + wraps the parser implementation + ''' + + from BeautifulSoup import BeautifulStoneSoup + + def __init__(self, value): + value = force_unicode(value) + self.soup = self.BeautifulStoneSoup(value) + + def __call__(self): + return unicode(self.soup) + +class HtmlParser(object): + '''Custom HTML parser + + wraps the parser implementation + ''' + + from BeautifulSoup import BeautifulSoup + + def __init__(self, value): + value = force_unicode(value) + self.soup = self.BeautifulSoup(value) + for tag in self.soup.fetch(recursive=False): + tag['xmlns'] = "http://www.w3.org/1999/xhtml" + + def __call__(self): + return unicode(self.soup) Added: azax/branches/plugin/selectors.py ============================================================================== --- (empty file) +++ azax/branches/plugin/selectors.py Sun Apr 9 18:44:12 2006 @@ -0,0 +1,37 @@ +# -*- coding: ISO-8859-15 -*- +# Copyright (c) 2006 +# Authors: +# Godefroid Chapelle <[EMAIL PROTECTED]> +# +# This program is free software; you can redistribute it and/or modify +# it under the terms of the GNU General Public License version 2 as published +# by the Free Software Foundation. +# +# This program is distributed in the hope that it will be useful, +# but WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +# GNU General Public License for more details. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write to the Free Software +# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA +# 02111-1307, USA. +# + +XPATH_SELECTOR = 'xpath' +CSS_SELECTOR = 'css' +HTMLID_SELECTOR = 'htmlid' + +class SelectorBase(object): + + def __init__(self, selector): + self.value = selector + +class XpathSelector(SelectorBase): + type = XPATH_SELECTOR + +class CssSelector(SelectorBase): + type = CSS_SELECTOR + +class HtmlIdSelector(SelectorBase): + type = HTMLID_SELECTOR Modified: azax/branches/plugin/tests/test_azaxview.py ============================================================================== --- azax/branches/plugin/tests/test_azaxview.py (original) +++ azax/branches/plugin/tests/test_azaxview.py Sun Apr 9 18:44:12 2006 @@ -68,14 +68,14 @@ factory="Products.Five.traversable.FiveTraversable" provides="zope.app.traversing.interfaces.ITraversable" /> - <!--adapter + <adapter for="*" factory="zope.app.traversing.adapters.Traverser" provides="zope.app.traversing.interfaces.ITraverser" - /--> + /> </configure>''')) - load_config('meta.zcml', package=Products.azax.plugins) - load_config('configure.zcml', package=Products.azax.plugins) + load_config('meta.zcml', package=Products.azax) + load_config('configure.zcml', package=Products.azax) def beforeTearDown(self): from zope.app.tests.placelesssetup import tearDown -- http://lists.nuxeo.com/mailman/listinfo/z3lab-checkins