From z3-checkins at codespeak.net Fri Apr 4 10:29:23 2008 From: z3-checkins at codespeak.net (z3-checkins at codespeak.net) Date: Fri, 4 Apr 2008 10:29:23 +0200 (CEST) Subject: SALE 73% OFF on VIAGRA® Message-ID: <20080404142820.9301.qmail@softbank126112089226.bbtec.net> An HTML attachment was scrubbed... URL: http://codespeak.net/pipermail/z3-checkins/attachments/20080404/e5d2afb2/attachment.htm From wiggy at codespeak.net Fri Apr 4 19:00:30 2008 From: wiggy at codespeak.net (wiggy at codespeak.net) Date: Fri, 4 Apr 2008 19:00:30 +0200 (CEST) Subject: [z3-checkins] r53342 - z3/deliverance/trunk/deliverance Message-ID: <20080404170030.0E5DA16A869@codespeak.net> Author: wiggy Date: Fri Apr 4 19:00:28 2008 New Revision: 53342 Modified: z3/deliverance/trunk/deliverance/proxyapp.py z3/deliverance/trunk/deliverance/wsgimiddleware.py Log: More serializer fixes Modified: z3/deliverance/trunk/deliverance/proxyapp.py ============================================================================== --- z3/deliverance/trunk/deliverance/proxyapp.py (original) +++ z3/deliverance/trunk/deliverance/proxyapp.py Fri Apr 4 19:00:28 2008 @@ -11,12 +11,15 @@ from paste.exceptions import errormiddleware from deliverance.wsgimiddleware import DeliveranceMiddleware from deliverance.relocateresponse import RelocateMiddleware +from deliverance.utils import get_serializer +from deliverance.utils import set_serializer class ProxyDeliveranceApp(object): def __init__(self, theme_uri, rule_uri, proxy, transparent=False, debug_headers=False, - relocate_content=False, renderer='py'): + relocate_content=False, renderer='py', + serializer=None): self.theme_uri = theme_uri, self.rule_uri = rule_uri, self.proxy = proxy @@ -24,7 +27,7 @@ self.debug_headers = debug_headers self.subapp = self.make_app() self.deliverance_app = DeliveranceMiddleware( - self.subapp, theme_uri, rule_uri, renderer) + self.subapp, theme_uri, rule_uri, renderer, serializer=serializer) self.relocate_content = relocate_content def make_app(self): @@ -38,6 +41,8 @@ return app def __call__(self, environ, start_response): + if get_serializer(environ, None) is None: + set_serializer(environ, self.deliverance_app.serializer) if self.relocate_content: reloc_app = RelocateMiddleware(self.run_subapp, old_href='http://'+self.proxy) return reloc_app(environ, start_response) @@ -108,6 +113,7 @@ renderer='py', transparent=False, debug_headers=False, relocate_content=False, merge_cache_control=False, + serializer=None, **kw): from paste.deploy.converters import asbool mount_points = {} @@ -150,6 +156,7 @@ debug_headers=asbool(debug_headers), relocate_content=asbool(relocate_content), renderer=renderer, - mount_points=mount_points) + mount_points=mount_points, + serializer=serializer) app = errormiddleware.make_error_middleware(app, global_conf) return app Modified: z3/deliverance/trunk/deliverance/wsgimiddleware.py ============================================================================== --- z3/deliverance/trunk/deliverance/wsgimiddleware.py (original) +++ z3/deliverance/trunk/deliverance/wsgimiddleware.py Fri Apr 4 19:00:28 2008 @@ -75,7 +75,7 @@ should be considered 'internal'(passed to the subapplication) and false if the requestshould be send over the network. - serializer: dotted name or entry point indicdating a callable used + serializer: dotted name or entry point indicating a callable used to post-process rendered output. Defaults to the '_toHTML' function above. """ From wiggy at codespeak.net Fri Apr 4 20:56:43 2008 From: wiggy at codespeak.net (wiggy at codespeak.net) Date: Fri, 4 Apr 2008 20:56:43 +0200 (CEST) Subject: [z3-checkins] r53354 - in z3/deliverance/trunk: . deliverance Message-ID: <20080404185643.5C53616A914@codespeak.net> Author: wiggy Date: Fri Apr 4 20:56:41 2008 New Revision: 53354 Added: z3/deliverance/trunk/deliverance/serializers.py (contents, props changed) Modified: z3/deliverance/trunk/CHANGES.txt z3/deliverance/trunk/deliverance/wsgimiddleware.py Log: Set me up the serializer Modified: z3/deliverance/trunk/CHANGES.txt ============================================================================== --- z3/deliverance/trunk/CHANGES.txt (original) +++ z3/deliverance/trunk/CHANGES.txt Fri Apr 4 20:56:41 2008 @@ -3,6 +3,7 @@ After 0.1.2 ----------- +- Add a new serializers file with HTML4 and XHTML serializers. - (wsgimiddleware) Expose all middleware constructor arguments via Paste config. Added: z3/deliverance/trunk/deliverance/serializers.py ============================================================================== --- (empty file) +++ z3/deliverance/trunk/deliverance/serializers.py Fri Apr 4 20:56:41 2008 @@ -0,0 +1,12 @@ +from lxml import etree +from htmlserialize import tostring + +def HTML4(content): + return tostring(content, + doctype_pair=("-//W3C//DTD HTML 4.01 Transitional//EN", + "http://www.w3.org/TR/html4/loose.dtd")) + +def XHTML(content): + return '' + \ + ''+ \ + etree.tostring(content) Modified: z3/deliverance/trunk/deliverance/wsgimiddleware.py ============================================================================== --- z3/deliverance/trunk/deliverance/wsgimiddleware.py (original) +++ z3/deliverance/trunk/deliverance/wsgimiddleware.py Fri Apr 4 20:56:41 2008 @@ -13,7 +13,6 @@ from paste.wsgilib import intercept_output from paste.request import construct_url from paste.response import header_value, replace_header -from htmlserialize import tostring from deliverance.utils import bool_from_string from deliverance.utils import DeliveranceError from deliverance.utils import DELIVERANCE_ERROR_PAGE @@ -43,10 +42,6 @@ IGNORE_URL_PATTERN = re.compile("^.*\.(%s)$" % '|'.join(IGNORE_EXTENSIONS)) -def _toHTML(content): - return tostring(content, - doctype_pair=("-//W3C//DTD HTML 4.01 Transitional//EN", - "http://www.w3.org/TR/html4/loose.dtd")) class DeliveranceMiddleware(object): """ @@ -98,7 +93,8 @@ self._is_internal_uri = resolve_callable(is_internal_uri) if serializer is None: - serializer = _toHTML + from deliverance.serializers import HTML4 + serializer = HTML4 self.serializer = serializer def get_renderer(self, environ): From rocky at codespeak.net Mon Apr 7 17:20:32 2008 From: rocky at codespeak.net (rocky at codespeak.net) Date: Mon, 7 Apr 2008 17:20:32 +0200 (CEST) Subject: [z3-checkins] r53528 - z3/deliverance/trunk/deliverance Message-ID: <20080407152032.DFD251684F5@codespeak.net> Author: rocky Date: Mon Apr 7 17:20:31 2008 New Revision: 53528 Modified: z3/deliverance/trunk/deliverance/wsgimiddleware.py Log: Fixed issue where theme_path was being used for rule uri generation. Modified: z3/deliverance/trunk/deliverance/wsgimiddleware.py ============================================================================== --- z3/deliverance/trunk/deliverance/wsgimiddleware.py (original) +++ z3/deliverance/trunk/deliverance/wsgimiddleware.py Mon Apr 7 17:20:31 2008 @@ -574,7 +574,7 @@ theme_uri = '/.deliverance/theme/%s' % os.path.basename(theme_path) if rule_uri.lower().startswith('file:'): rule_path = filename_for_uri(rule_uri) - rule_dir = os.path.dirname(theme_path) + rule_dir = os.path.dirname(rule_path) if statics.get('/.deliverance/theme') == rule_dir: rule_uri = '/.deliverance/theme/%s' % os.path.basename(rule_path) else: From ianb at codespeak.net Tue Apr 8 23:47:07 2008 From: ianb at codespeak.net (ianb at codespeak.net) Date: Tue, 8 Apr 2008 23:47:07 +0200 (CEST) Subject: [z3-checkins] r53599 - in z3/deliverance/trunk: . deliverance Message-ID: <20080408214707.D5D6016B175@codespeak.net> Author: ianb Date: Tue Apr 8 23:47:05 2008 New Revision: 53599 Modified: z3/deliverance/trunk/CHANGES.txt z3/deliverance/trunk/deliverance/wsgimiddleware.py Log: Remove Range header in addition to other conditional headers Modified: z3/deliverance/trunk/CHANGES.txt ============================================================================== --- z3/deliverance/trunk/CHANGES.txt (original) +++ z3/deliverance/trunk/CHANGES.txt Tue Apr 8 23:47:05 2008 @@ -11,6 +11,9 @@ - (wsgimiddleware) Check for environmental overrides of theme URI, rule URI, serializer, and apply. +- (wsgimiddleware) Strip out range-related headers in addition to + the other conditional headers. + - (utils) Added APIs for parsing non-string config values ('resolve_callable', 'resolve_dotted_or_egg', 'bool_from_string'). Modified: z3/deliverance/trunk/deliverance/wsgimiddleware.py ============================================================================== --- z3/deliverance/trunk/deliverance/wsgimiddleware.py (original) +++ z3/deliverance/trunk/deliverance/wsgimiddleware.py Tue Apr 8 23:47:05 2008 @@ -203,13 +203,11 @@ environ['QUERY_STRING'] = qs[:-len('¬heme')] return self.app(environ, start_response) - # unsupported - if 'HTTP_ACCEPT_ENCODING' in environ: - environ['HTTP_ACCEPT_ENCODING'] = '' - if 'HTTP_IF_MATCH' in environ: - del environ['HTTP_IF_MATCH'] - if 'HTTP_IF_UNMODIFIED_SINCE' in environ: - del environ['HTTP_IF_UNMODIFIED_SINCE'] + # unsupported + for key in ['HTTP_ACCEPT_ENCODING', 'HTTP_IF_MATCH', 'HTTP_IF_UNMODIFIED_SINCE', + 'HTTP_RANGE', 'HTTP_IF_RANGE']: + if key in environ: + del environ[key] orig_environ = environ.copy() From ianb at codespeak.net Wed Apr 9 23:19:19 2008 From: ianb at codespeak.net (ianb at codespeak.net) Date: Wed, 9 Apr 2008 23:19:19 +0200 (CEST) Subject: [z3-checkins] r53632 - z3/deliverance/trunk/deliverance Message-ID: <20080409211919.48A362A018F@codespeak.net> Author: ianb Date: Wed Apr 9 23:19:16 2008 New Revision: 53632 Modified: z3/deliverance/trunk/deliverance/wsgimiddleware.py Log: Add in the filtering in another place where subrequests are made Modified: z3/deliverance/trunk/deliverance/wsgimiddleware.py ============================================================================== --- z3/deliverance/trunk/deliverance/wsgimiddleware.py (original) +++ z3/deliverance/trunk/deliverance/wsgimiddleware.py Wed Apr 9 23:19:16 2008 @@ -382,10 +382,10 @@ # eliminate validation headers, we want the content - if 'HTTP_IF_MODIFIED_SINCE' in fetcher.environ: - del fetcher.environ['HTTP_IF_MODIFIED_SINCE'] - if 'HTTP_IF_NONE_MATCH' in fetcher.environ: - del fetcher.environ['HTTP_IF_NONE_MATCH'] + for key in ['HTTP_ACCEPT_ENCODING', 'HTTP_IF_MATCH', 'HTTP_IF_UNMODIFIED_SINCE', + 'HTTP_RANGE', 'HTTP_IF_RANGE']: + if key in environ: + del environ[key] fetcher.environ['HTTP_CACHE_CONTROL'] = 'no-cache' From slinkp at codespeak.net Thu Apr 10 01:02:05 2008 From: slinkp at codespeak.net (slinkp at codespeak.net) Date: Thu, 10 Apr 2008 01:02:05 +0200 (CEST) Subject: [z3-checkins] r53637 - z3/deliverance/DeliveranceVHoster/trunk Message-ID: <20080409230205.3C6E5169EC1@codespeak.net> Author: slinkp Date: Thu Apr 10 01:01:54 2008 New Revision: 53637 Modified: z3/deliverance/DeliveranceVHoster/trunk/fassembler_config.ini_tmpl Log: work in progress toward making TOPP's deliverance themes work out-of-the-box. Modified: z3/deliverance/DeliveranceVHoster/trunk/fassembler_config.ini_tmpl ============================================================================== --- z3/deliverance/DeliveranceVHoster/trunk/fassembler_config.ini_tmpl (original) +++ z3/deliverance/DeliveranceVHoster/trunk/fassembler_config.ini_tmpl Thu Apr 10 01:01:54 2008 @@ -28,10 +28,11 @@ # (note: this matches the *environmental key*, not the original header) clean_environ_headers_regex = ^HTTP_X_OPENPLANS -# This makes every site like the "master" www.openplans.org site, -# hosting multiple projects. If you set it to a specific domain, then -# any other domains will be treated as project vhosts: -master_site_domain = auto +# master_site_domain = "auto" makes every site like the "master" +# www.openplans.org site, hosting multiple projects. If you set it to +# a specific domain, then any other domains will be treated as project +# vhosts: +master_site_domain = {{project.req_settings.get('master_site_domain', 'auto'}} # WARNING: *THE LINE BELOW MUST BE FALSE ON A PRODUCTION ENVIRONMENT* @@ -68,6 +69,12 @@ transcluder_ok_hosts = openplans.org|(.*)\.openplans.org|(.*)\.localhost.openplans\.org|localhost|127.0.0.1 transcluder_pool_size = 0 -default_theme_uri = {{project.req_settings.get('default_theme_uri', 'http://www.openplans.org/theme.html')}} +# Where to load the default theme. +# Note re. the defaults: fassembler tries to get this setting from the +# project's requirements file; if it's not set there, fassembler +# assumes deliverance is the outermost server in your stack so the +# theme can be requested from deliverance itself. +# This is at least better than the old fallback of hitting openplans.org. +default_theme_uri = {{project.req_settings.get('default_theme_uri', 'http://localhost:%d/theme.html' % env.base_port)}} topp_secret_filename = {{env.config.get('general', 'topp_secret_filename')}} From slinkp at codespeak.net Thu Apr 10 01:09:23 2008 From: slinkp at codespeak.net (slinkp at codespeak.net) Date: Thu, 10 Apr 2008 01:09:23 +0200 (CEST) Subject: [z3-checkins] r53638 - z3/deliverance/DeliveranceVHoster/trunk Message-ID: <20080409230923.2806B169F21@codespeak.net> Author: slinkp Date: Thu Apr 10 01:09:21 2008 New Revision: 53638 Modified: z3/deliverance/DeliveranceVHoster/trunk/fassembler_config.ini_tmpl Log: fix typo: missing paren Modified: z3/deliverance/DeliveranceVHoster/trunk/fassembler_config.ini_tmpl ============================================================================== --- z3/deliverance/DeliveranceVHoster/trunk/fassembler_config.ini_tmpl (original) +++ z3/deliverance/DeliveranceVHoster/trunk/fassembler_config.ini_tmpl Thu Apr 10 01:09:21 2008 @@ -32,7 +32,7 @@ # www.openplans.org site, hosting multiple projects. If you set it to # a specific domain, then any other domains will be treated as project # vhosts: -master_site_domain = {{project.req_settings.get('master_site_domain', 'auto'}} +master_site_domain = {{project.req_settings.get('master_site_domain', 'auto')}} # WARNING: *THE LINE BELOW MUST BE FALSE ON A PRODUCTION ENVIRONMENT* From wiggy at codespeak.net Sat Apr 12 10:58:09 2008 From: wiggy at codespeak.net (wiggy at codespeak.net) Date: Sat, 12 Apr 2008 10:58:09 +0200 (CEST) Subject: [z3-checkins] r53711 - z3/deliverance/trunk/deliverance Message-ID: <20080412085809.7E63039B5C7@codespeak.net> Author: wiggy Date: Sat Apr 12 10:58:07 2008 New Revision: 53711 Modified: z3/deliverance/trunk/deliverance/fixuplinks.py z3/deliverance/trunk/deliverance/serializers.py z3/deliverance/trunk/deliverance/wsgimiddleware.py Log: Pass environ to the serializer so they can make serialization decisions based on the environment Modified: z3/deliverance/trunk/deliverance/fixuplinks.py ============================================================================== --- z3/deliverance/trunk/deliverance/fixuplinks.py (original) +++ z3/deliverance/trunk/deliverance/fixuplinks.py Sat Apr 12 10:58:07 2008 @@ -15,7 +15,7 @@ doc = decodeAndParseHTML(doc) fixup_links(doc, link_repl_func, remove_base_tags=remove_base_tags) serializer = get_serializer(environ, tostring) - return serializer(doc) + return serializer(environ, doc) def fixup_links(doc, link_repl_func, remove_base_tags=True): Modified: z3/deliverance/trunk/deliverance/serializers.py ============================================================================== --- z3/deliverance/trunk/deliverance/serializers.py (original) +++ z3/deliverance/trunk/deliverance/serializers.py Sat Apr 12 10:58:07 2008 @@ -1,12 +1,12 @@ from lxml import etree from htmlserialize import tostring -def HTML4(content): +def HTML4(environ, content): return tostring(content, doctype_pair=("-//W3C//DTD HTML 4.01 Transitional//EN", "http://www.w3.org/TR/html4/loose.dtd")) -def XHTML(content): +def XHTML(environ, content): return '' + \ ''+ \ etree.tostring(content) Modified: z3/deliverance/trunk/deliverance/wsgimiddleware.py ============================================================================== --- z3/deliverance/trunk/deliverance/wsgimiddleware.py (original) +++ z3/deliverance/trunk/deliverance/wsgimiddleware.py Sat Apr 12 10:58:07 2008 @@ -266,7 +266,7 @@ """ content = self.get_renderer(orig_environ).render(parseHTML(body)) serializer = get_serializer(environ, self.serializer) - return serializer(content) + return serializer(environ, content) def rebuild_check(self, environ, start_response): From wiggy at codespeak.net Wed Apr 16 09:43:54 2008 From: wiggy at codespeak.net (wiggy at codespeak.net) Date: Wed, 16 Apr 2008 09:43:54 +0200 (CEST) Subject: [z3-checkins] r53819 - z3/deliverance/trunk/deliverance Message-ID: <20080416074354.843D949816D@codespeak.net> Author: wiggy Date: Wed Apr 16 09:43:52 2008 New Revision: 53819 Modified: z3/deliverance/trunk/deliverance/wsgimiddleware.py Log: Fixes from Reinout: - we need to tweak the fetcher's environ, not the main one - add some extra HTTP headers that should be removed Modified: z3/deliverance/trunk/deliverance/wsgimiddleware.py ============================================================================== --- z3/deliverance/trunk/deliverance/wsgimiddleware.py (original) +++ z3/deliverance/trunk/deliverance/wsgimiddleware.py Wed Apr 16 09:43:52 2008 @@ -383,11 +383,11 @@ # eliminate validation headers, we want the content for key in ['HTTP_ACCEPT_ENCODING', 'HTTP_IF_MATCH', 'HTTP_IF_UNMODIFIED_SINCE', - 'HTTP_RANGE', 'HTTP_IF_RANGE']: - if key in environ: - del environ[key] + 'HTTP_RANGE', 'HTTP_IF_RANGE', + 'HTTP_IF_NONE_MATCH', 'HTTP_IF_MODIFIED_SINCE']: + if key in fetcher.environ: + del fetcher.environ[key] fetcher.environ['HTTP_CACHE_CONTROL'] = 'no-cache' - status, headers, body = fetcher.wsgi_get() From z3-checkins at codespeak.net Mon Apr 21 11:28:47 2008 From: z3-checkins at codespeak.net (z3-checkins at codespeak.net) Date: Mon, 21 Apr 2008 11:28:47 +0200 (CEST) Subject: [z3-checkins] Your Featured Products of the Week‏ Message-ID: <20080421142745.3002.qmail@dsl88.238-2242.ttnet.net.tr> An HTML attachment was scrubbed... URL: http://codespeak.net/pipermail/z3-checkins/attachments/20080421/8bb12811/attachment-0001.htm From z3-checkins at codespeak.net Thu Apr 24 17:08:49 2008 From: z3-checkins at codespeak.net (z3-checkins at codespeak.net) Date: Thu, 24 Apr 2008 17:08:49 +0200 (CEST) Subject: [z3-checkins] Thu, 24 Apr 2008 07:07:41 +0300 Dear z3-checkins@codespeak.net April 84% 0FF Message-ID: <20080424100741.4009.qmail@credit-6-ppp166.tts.nov.ru> An HTML attachment was scrubbed... URL: http://codespeak.net/pipermail/z3-checkins/attachments/20080424/8acf6504/attachment.htm From z3-checkins at codespeak.net Sun Apr 27 20:53:38 2008 From: z3-checkins at codespeak.net (VIAGRA ® Official Site) Date: Sun, 27 Apr 2008 20:53:38 +0200 (CEST) Subject: [z3-checkins] Dear z3-checkins@codespeak.net April 89% 0FF Message-ID: <20080427095223.45498.qmail@cp430783-b.venlo1.lb.home.nl> An HTML attachment was scrubbed... URL: http://codespeak.net/pipermail/z3-checkins/attachments/20080427/9473cdfa/attachment.htm From z3-checkins at codespeak.net Tue May 6 15:02:53 2008 From: z3-checkins at codespeak.net (z3-checkins at codespeak.net) Date: Tue, 6 May 2008 15:02:53 +0200 (CEST) Subject: [z3-checkins] Discover a world of comfort. Designer Footwear and Bags Deals for you to enjoy. Message-ID: <20080506080306.4058.qmail@ppp92-100-41-81.pppoe.avangarddsl.ru> Ladies and Gentlemen, Get Ready for.. Thought I would let you know about the Fashion Footwear and Bags SPRING Sale! Men and Women Designer Shoes, Heels, Sandals and Boots also Women Bags, All Half-OFF, Buy Direct, Forget Department Store Prices, Get Exclusive 2008 D&G, Gucci, Versace, Prada, Chanel, Christian Dior, Dsquared, Uggs and More! FREE International Shipping on all Orders! http://www.mueblesnature.ueuo.com/offer/ From magicbronson at codespeak.net Tue May 6 21:00:31 2008 From: magicbronson at codespeak.net (magicbronson at codespeak.net) Date: Tue, 6 May 2008 21:00:31 +0200 (CEST) Subject: [z3-checkins] r54498 - z3/deliverance/DeliveranceVHoster/trunk/dvhoster Message-ID: <20080506190031.5138C1683E4@codespeak.net> Author: magicbronson Date: Tue May 6 21:00:30 2008 New Revision: 54498 Modified: z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dispatcher.py Log: destroy errant tab Modified: z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dispatcher.py ============================================================================== --- z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dispatcher.py (original) +++ z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dispatcher.py Tue May 6 21:00:30 2008 @@ -68,7 +68,7 @@ self.logger = logger # transcluder configuration - self.transcluder_enabled = asbool(app_conf.get('transcluder_enabled',False)) + self.transcluder_enabled = asbool(app_conf.get('transcluder_enabled', False)) ok_hosts = app_conf.get('transcluder_ok_hosts') if not ok_hosts or ok_hosts == 'all': From magicbronson at codespeak.net Fri May 9 19:22:12 2008 From: magicbronson at codespeak.net (magicbronson at codespeak.net) Date: Fri, 9 May 2008 19:22:12 +0200 (CEST) Subject: [z3-checkins] r54606 - z3/deliverance/DeliveranceVHoster/trunk Message-ID: <20080509172212.C3D4B4981EB@codespeak.net> Author: magicbronson Date: Fri May 9 19:22:12 2008 New Revision: 54606 Modified: z3/deliverance/DeliveranceVHoster/trunk/fassembler_config.ini_tmpl Log: default_theme_uri should default to "/theme.html", not "http://localhost:XXXX/theme.html". "/" points to the top of the deliverance stack (which is configured in dvhoster to point to Zope), but deliverance will now rewrite relative links in theme.html correctly based on the host the client requested, so this gets us what we want. Also, deliverance will now make this request inside wsgimiddleware rather than having to open a socket. Modified: z3/deliverance/DeliveranceVHoster/trunk/fassembler_config.ini_tmpl ============================================================================== --- z3/deliverance/DeliveranceVHoster/trunk/fassembler_config.ini_tmpl (original) +++ z3/deliverance/DeliveranceVHoster/trunk/fassembler_config.ini_tmpl Fri May 9 19:22:12 2008 @@ -75,6 +75,6 @@ # assumes deliverance is the outermost server in your stack so the # theme can be requested from deliverance itself. # This is at least better than the old fallback of hitting openplans.org. -default_theme_uri = {{project.req_settings.get('default_theme_uri', 'http://localhost:%d/theme.html' % env.base_port)}} +default_theme_uri = {{project.req_settings.get('default_theme_uri', '/theme.html')}} topp_secret_filename = {{env.config.get('general', 'topp_secret_filename')}} From ianb at codespeak.net Thu May 15 22:15:41 2008 From: ianb at codespeak.net (ianb at codespeak.net) Date: Thu, 15 May 2008 22:15:41 +0200 (CEST) Subject: [z3-checkins] r54764 - z3/deliverance/trunk/deliverance Message-ID: <20080515201541.3AC601684C8@codespeak.net> Author: ianb Date: Thu May 15 22:15:39 2008 New Revision: 54764 Modified: z3/deliverance/trunk/deliverance/cache_utils.py Log: catch int() exceptions properly Modified: z3/deliverance/trunk/deliverance/cache_utils.py ============================================================================== --- z3/deliverance/trunk/deliverance/cache_utils.py (original) +++ z3/deliverance/trunk/deliverance/cache_utils.py Thu May 15 22:15:39 2008 @@ -227,7 +227,7 @@ return tags try: tag_len = int(tag_len) - except: + except ValueError: return {} if len(composite_tag) >= tag_len: From magicbronson at codespeak.net Thu May 15 22:49:54 2008 From: magicbronson at codespeak.net (magicbronson at codespeak.net) Date: Thu, 15 May 2008 22:49:54 +0200 (CEST) Subject: [z3-checkins] r54765 - z3/deliverance/DeliveranceVHoster/trunk/dvhoster Message-ID: <20080515204954.52F1A168431@codespeak.net> Author: magicbronson Date: Thu May 15 22:49:50 2008 New Revision: 54765 Modified: z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dispatcher.py z3/deliverance/DeliveranceVHoster/trunk/dvhoster/wsgiapp.py Log: refactor creation of Transcluder middleware. now it's created in wsgiapp.py which is a less surprising place for it. Modified: z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dispatcher.py ============================================================================== --- z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dispatcher.py (original) +++ z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dispatcher.py Thu May 15 22:49:50 2008 @@ -9,8 +9,6 @@ from wsgifilter import proxyapp from wsgifilter import relocateresponse from deliverance.wsgimiddleware import DeliveranceMiddleware -from dvhoster.socket_error import SocketErrorToHTTPServerException -from dvhoster.socket_error import RetryOnceOnSocketError from dvhoster.model import DomainInfoSet, DomainInfoApp from dvhoster import current_environ from dvhoster.debuginterp import Renderer @@ -19,9 +17,6 @@ from dvhoster import uritemplate from dvhoster.scrubber import scrub_environ_host -import transcluder -from transcluder.middleware import TranscluderMiddleware - from paste import fileapp # I hate this in-memory cache of files, so I'm globally disabling it # here at least: @@ -67,29 +62,6 @@ logger = make_logger(app_conf.get('logger'), 'dvhoster') self.logger = logger - # transcluder configuration - self.transcluder_enabled = asbool(app_conf.get('transcluder_enabled', False)) - ok_hosts = app_conf.get('transcluder_ok_hosts') - - if not ok_hosts or ok_hosts == 'all': - self.transcluder_ok_hosts = transcluder.helpers.all_urls - elif ok_hosts == 'none': - self.transcluder_ok_hosts = transcluder.helpers.no_urls - elif ok_hosts == 'localhost': - self.transcluder_ok_hosts = transcluder.helpers.localhost_only - else: - self.transcluder_ok_hosts = transcluder.helpers.make_regex_predicate(ok_hosts) - - self.transcluder_deptracker = transcluder.deptracker.DependencyTracker() - - poolsize = 0 - try: - poolsize = int(app_conf.get('transcluder_pool_size')) - except: - pass - - self.transcluder_pool = transcluder.tasklist.TaskList(poolsize=poolsize) - def __call__(self, environ, start_response): """ WSGI interface @@ -181,15 +153,6 @@ remote=remote_uri, force_host=True) - if self.transcluder_enabled: - app = TranscluderMiddleware(app, - deptracker=self.transcluder_deptracker, - tasklist=self.transcluder_pool, - include_predicate=self.transcluder_ok_hosts, - recursion_predicate=self.transcluder_ok_hosts) - app = RetryOnceOnSocketError(app) - app = SocketErrorToHTTPServerException(app) - if should_theme_uri: if self.rewrite_links: app = relocateresponse.RelocateMiddleware( Modified: z3/deliverance/DeliveranceVHoster/trunk/dvhoster/wsgiapp.py ============================================================================== --- z3/deliverance/DeliveranceVHoster/trunk/dvhoster/wsgiapp.py (original) +++ z3/deliverance/DeliveranceVHoster/trunk/dvhoster/wsgiapp.py Thu May 15 22:49:50 2008 @@ -10,11 +10,22 @@ from eyvind.lib.authmiddleware import AuthenticationMiddleware from dvhoster.custom_error import CustomErrorHTTPExceptionHandler +import transcluder +from transcluder.middleware import TranscluderMiddleware +from dvhoster.socket_error import RetryOnceOnSocketError, SocketErrorToHTTPServerException + + def make_app(global_conf, **app_conf): """Create a WSGI application and return it""" custom_error_dir = app_conf['custom_error_dir'] = app_conf.get('custom_error_dir', global_conf.get('custom_error_dir','.')) + app = DeliveranceDispatcher(app_conf) app = CustomErrorHTTPExceptionHandler(app, custom_error_dir) + + transcluder_enabled = asbool(app_conf.get('transcluder_enabled', False)) + if transcluder_enabled: + app = _create_transcluder(app, app_conf) + app = RecursiveMiddleware(app) app = AuthenticationMiddleware(app, app_conf) app = EnvironScrubber(app, app_conf) @@ -30,4 +41,32 @@ folded_conf.update(app_conf) app = ErrorMiddleware( app, global_conf=folded_conf) + + return app + +def _create_transcluder(app, app_conf): + ok_hosts = app_conf.get('transcluder_ok_hosts') + + if not ok_hosts or ok_hosts == 'all': + transcluder_ok_hosts = transcluder.helpers.all_urls + elif ok_hosts == 'none': + transcluder_ok_hosts = transcluder.helpers.no_urls + elif ok_hosts == 'localhost': + transcluder_ok_hosts = transcluder.helpers.localhost_only + else: + transcluder_ok_hosts = transcluder.helpers.make_regex_predicate(ok_hosts) + + transcluder_deptracker = transcluder.deptracker.DependencyTracker() + + poolsize = int(app_conf.get('transcluder_pool_size', 0)) + transcluder_pool = transcluder.tasklist.TaskList(poolsize=poolsize) + + app = TranscluderMiddleware(app, + deptracker=transcluder_deptracker, + tasklist=transcluder_pool, + include_predicate=transcluder_ok_hosts, + recursion_predicate=transcluder_ok_hosts) + app = RetryOnceOnSocketError(app) + app = SocketErrorToHTTPServerException(app) + return app From magicbronson at codespeak.net Thu May 15 23:20:04 2008 From: magicbronson at codespeak.net (magicbronson at codespeak.net) Date: Thu, 15 May 2008 23:20:04 +0200 (CEST) Subject: [z3-checkins] r54767 - z3/deliverance/DeliveranceVHoster/trunk Message-ID: <20080515212004.5D594168471@codespeak.net> Author: magicbronson Date: Thu May 15 23:20:03 2008 New Revision: 54767 Modified: z3/deliverance/DeliveranceVHoster/trunk/fassembler_config.ini_tmpl Log: add setting 'auth_enabled' to control whether to create AuthenticationMiddleware Modified: z3/deliverance/DeliveranceVHoster/trunk/fassembler_config.ini_tmpl ============================================================================== --- z3/deliverance/DeliveranceVHoster/trunk/fassembler_config.ini_tmpl (original) +++ z3/deliverance/DeliveranceVHoster/trunk/fassembler_config.ini_tmpl Thu May 15 23:20:03 2008 @@ -77,4 +77,7 @@ # This is at least better than the old fallback of hitting openplans.org. default_theme_uri = {{project.req_settings.get('default_theme_uri', '/theme.html')}} + +# Specifies whether to load authentication middleware +auth_enabled = True topp_secret_filename = {{env.config.get('general', 'topp_secret_filename')}} From magicbronson at codespeak.net Thu May 15 23:21:15 2008 From: magicbronson at codespeak.net (magicbronson at codespeak.net) Date: Thu, 15 May 2008 23:21:15 +0200 (CEST) Subject: [z3-checkins] r54768 - z3/deliverance/DeliveranceVHoster/trunk/dvhoster Message-ID: <20080515212115.DB4F5168471@codespeak.net> Author: magicbronson Date: Thu May 15 23:21:14 2008 New Revision: 54768 Modified: z3/deliverance/DeliveranceVHoster/trunk/dvhoster/wsgiapp.py Log: - use new auth_enabled setting to conditionally load eyvind - AuthenticationMiddleware method was renamed make_auth_middleware Modified: z3/deliverance/DeliveranceVHoster/trunk/dvhoster/wsgiapp.py ============================================================================== --- z3/deliverance/DeliveranceVHoster/trunk/dvhoster/wsgiapp.py (original) +++ z3/deliverance/DeliveranceVHoster/trunk/dvhoster/wsgiapp.py Thu May 15 23:21:14 2008 @@ -7,7 +7,7 @@ from paste.exceptions.errormiddleware import ErrorMiddleware from dvhoster.dispatcher import DeliveranceDispatcher from dvhoster.scrubber import EnvironScrubber -from eyvind.lib.authmiddleware import AuthenticationMiddleware +from eyvind.lib.authmiddleware import make_auth_middleware from dvhoster.custom_error import CustomErrorHTTPExceptionHandler import transcluder @@ -27,7 +27,11 @@ app = _create_transcluder(app, app_conf) app = RecursiveMiddleware(app) - app = AuthenticationMiddleware(app, app_conf) + + auth_enabled = asbool(app_conf.get('auth_enabled', True)) + if auth_enabled: + app = make_auth_middleware(app, app_conf) + app = EnvironScrubber(app, app_conf) app = RegistryManager(app) debug = app_conf['debug'] = asbool(app_conf.get('debug', global_conf.get('debug'))) From z3-checkins at codespeak.net Fri May 16 10:02:24 2008 From: z3-checkins at codespeak.net (VIAGRA ® Official Site) Date: Fri, 16 May 2008 10:02:24 +0200 (CEST) Subject: [z3-checkins] Dear z3-checkins@codespeak.net May 83% 0FF Message-ID: <20080516070057.16529.qmail@pppoe.77.43.145.86.ccl.perm.ru> An HTML attachment was scrubbed... URL: http://codespeak.net/pipermail/z3-checkins/attachments/20080516/fca88e3f/attachment.htm From ianb at codespeak.net Fri May 16 23:56:20 2008 From: ianb at codespeak.net (ianb at codespeak.net) Date: Fri, 16 May 2008 23:56:20 +0200 (CEST) Subject: [z3-checkins] r54799 - z3/deliverance/sandbox Message-ID: <20080516215620.94F97398009@codespeak.net> Author: ianb Date: Fri May 16 23:56:17 2008 New Revision: 54799 Added: z3/deliverance/sandbox/ Log: sandbox area From ianb at codespeak.net Fri May 16 23:56:44 2008 From: ianb at codespeak.net (ianb at codespeak.net) Date: Fri, 16 May 2008 23:56:44 +0200 (CEST) Subject: [z3-checkins] r54800 - z3/deliverance/sandbox/ianb Message-ID: <20080516215644.E8FCE398009@codespeak.net> Author: ianb Date: Fri May 16 23:56:43 2008 New Revision: 54800 Added: z3/deliverance/sandbox/ianb/ Log: sandbox area for Ian From ianb at codespeak.net Fri May 16 23:58:34 2008 From: ianb at codespeak.net (ianb at codespeak.net) Date: Fri, 16 May 2008 23:58:34 +0200 (CEST) Subject: [z3-checkins] r54801 - in z3/deliverance/sandbox/ianb/deliverance: . branches tags trunk Message-ID: <20080516215834.444FC398009@codespeak.net> Author: ianb Date: Fri May 16 23:58:32 2008 New Revision: 54801 Added: z3/deliverance/sandbox/ianb/deliverance/ z3/deliverance/sandbox/ianb/deliverance/branches/ z3/deliverance/sandbox/ianb/deliverance/tags/ z3/deliverance/sandbox/ianb/deliverance/trunk/ Log: New project deliverance From z3-checkins at codespeak.net Sun May 18 21:20:27 2008 From: z3-checkins at codespeak.net (VIAGRA ® Official Site) Date: Sun, 18 May 2008 21:20:27 +0200 (CEST) Subject: [z3-checkins] Dear z3-checkins@codespeak.net May 87% 0FF Message-ID: <20080518101856.3264.qmail@d90-129-111-194.cust.tele2.pl> An HTML attachment was scrubbed... URL: http://codespeak.net/pipermail/z3-checkins/attachments/20080518/efa256b6/attachment.htm From ianb at codespeak.net Mon May 19 17:25:41 2008 From: ianb at codespeak.net (ianb at codespeak.net) Date: Mon, 19 May 2008 17:25:41 +0200 (CEST) Subject: [z3-checkins] r54948 - in z3/deliverance/sandbox/ianb/deliverance/trunk: . deliverance docs Message-ID: <20080519152541.E2FB716841D@codespeak.net> Author: ianb Date: Mon May 19 17:25:40 2008 New Revision: 54948 Added: z3/deliverance/sandbox/ianb/deliverance/trunk/deliverance/ z3/deliverance/sandbox/ianb/deliverance/trunk/deliverance/__init__.py (contents, props changed) z3/deliverance/sandbox/ianb/deliverance/trunk/docs/ z3/deliverance/sandbox/ianb/deliverance/trunk/docs/license.txt (contents, props changed) z3/deliverance/sandbox/ianb/deliverance/trunk/setup.cfg z3/deliverance/sandbox/ianb/deliverance/trunk/setup.py (contents, props changed) Modified: z3/deliverance/sandbox/ianb/deliverance/trunk/ (props changed) Log: basic layout plus some planning docs Added: z3/deliverance/sandbox/ianb/deliverance/trunk/deliverance/__init__.py ============================================================================== --- (empty file) +++ z3/deliverance/sandbox/ianb/deliverance/trunk/deliverance/__init__.py Mon May 19 17:25:40 2008 @@ -0,0 +1 @@ +# Added: z3/deliverance/sandbox/ianb/deliverance/trunk/docs/license.txt ============================================================================== --- (empty file) +++ z3/deliverance/sandbox/ianb/deliverance/trunk/docs/license.txt Mon May 19 17:25:40 2008 @@ -0,0 +1,20 @@ +Copyright (c) 2007 + +Permission is hereby granted, free of charge, to any person obtaining +a copy of this software and associated documentation files (the +"Software"), to deal in the Software without restriction, including +without limitation the rights to use, copy, modify, merge, publish, +distribute, sublicense, and/or sell copies of the Software, and to +permit persons to whom the Software is furnished to do so, subject to +the following conditions: + +The above copyright notice and this permission notice shall be +included in all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, +EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF +MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND +NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE +LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION +OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION +WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. Added: z3/deliverance/sandbox/ianb/deliverance/trunk/setup.cfg ============================================================================== --- (empty file) +++ z3/deliverance/sandbox/ianb/deliverance/trunk/setup.cfg Mon May 19 17:25:40 2008 @@ -0,0 +1,3 @@ +[egg_info] +tag_build = dev +tag_svn_revision = true Added: z3/deliverance/sandbox/ianb/deliverance/trunk/setup.py ============================================================================== --- (empty file) +++ z3/deliverance/sandbox/ianb/deliverance/trunk/setup.py Mon May 19 17:25:40 2008 @@ -0,0 +1,26 @@ +from setuptools import setup, find_packages +import sys, os + +version = '0.2' + +setup(name='deliverance', + version=version, + description="", + long_description="""\ +""", + classifiers=[], # Get strings from http://pypi.python.org/pypi?%3Aaction=list_classifiers + keywords='', + author='', + author_email='', + url='http://openplans.org/projects/deliverance/', + license='MIT', + packages=find_packages(exclude=['ez_setup', 'examples', 'tests']), + include_package_data=True, + zip_safe=False, + install_requires=[ + "lxml", + ], + entry_points=""" + # -*- Entry points: -*- + """, + ) From paul at codespeak.net Mon May 19 21:32:08 2008 From: paul at codespeak.net (paul at codespeak.net) Date: Mon, 19 May 2008 21:32:08 +0200 (CEST) Subject: [z3-checkins] r54960 - z3/deliverance/sandboxes/paul/docs Message-ID: <20080519193208.71FD316853D@codespeak.net> Author: paul Date: Mon May 19 21:32:05 2008 New Revision: 54960 Modified: z3/deliverance/sandboxes/paul/docs/genindex.html (props changed) z3/deliverance/sandboxes/paul/docs/index.html (props changed) z3/deliverance/sandboxes/paul/docs/modindex.html (props changed) z3/deliverance/sandboxes/paul/docs/search.html (props changed) z3/deliverance/sandboxes/paul/docs/step01.html (props changed) z3/deliverance/sandboxes/paul/docs/step02.html (props changed) z3/deliverance/sandboxes/paul/docs/step03.html (props changed) Log: Correct mimetype From paul at codespeak.net Mon May 19 21:32:41 2008 From: paul at codespeak.net (paul at codespeak.net) Date: Mon, 19 May 2008 21:32:41 +0200 (CEST) Subject: [z3-checkins] r54961 - z3/deliverance/sandboxes/paul/docs/_static Message-ID: <20080519193241.522B3168528@codespeak.net> Author: paul Date: Mon May 19 21:32:40 2008 New Revision: 54961 Modified: z3/deliverance/sandboxes/paul/docs/_static/admin.css (props changed) z3/deliverance/sandboxes/paul/docs/_static/default.css (props changed) z3/deliverance/sandboxes/paul/docs/_static/pygments.css (props changed) z3/deliverance/sandboxes/paul/docs/_static/rightsidebar.css (props changed) z3/deliverance/sandboxes/paul/docs/_static/sphinxdoc.css (props changed) z3/deliverance/sandboxes/paul/docs/_static/stickysidebar.css (props changed) z3/deliverance/sandboxes/paul/docs/_static/traditional.css (props changed) Log: Correct mimetype From paul at codespeak.net Mon May 19 21:35:19 2008 From: paul at codespeak.net (paul at codespeak.net) Date: Mon, 19 May 2008 21:35:19 +0200 (CEST) Subject: [z3-checkins] r54962 - in z3/deliverance/sandboxes/paul/dvng: . step01 step02 step03 Message-ID: <20080519193519.278A3168540@codespeak.net> Author: paul Date: Mon May 19 21:35:17 2008 New Revision: 54962 Added: z3/deliverance/sandboxes/paul/dvng/conf.py z3/deliverance/sandboxes/paul/dvng/index.rst z3/deliverance/sandboxes/paul/dvng/step01/ z3/deliverance/sandboxes/paul/dvng/step01.rst z3/deliverance/sandboxes/paul/dvng/step01/content.html z3/deliverance/sandboxes/paul/dvng/step01/content.xml (contents, props changed) z3/deliverance/sandboxes/paul/dvng/step01/dvfinalstage.xsl z3/deliverance/sandboxes/paul/dvng/step01/result.html z3/deliverance/sandboxes/paul/dvng/step01/theme.html z3/deliverance/sandboxes/paul/dvng/step01/xform.py z3/deliverance/sandboxes/paul/dvng/step02/ z3/deliverance/sandboxes/paul/dvng/step02.rst z3/deliverance/sandboxes/paul/dvng/step02/compiler.xsl z3/deliverance/sandboxes/paul/dvng/step02/content.html z3/deliverance/sandboxes/paul/dvng/step02/dvfinalstage.xsl z3/deliverance/sandboxes/paul/dvng/step02/rules.xml z3/deliverance/sandboxes/paul/dvng/step02/theme.html z3/deliverance/sandboxes/paul/dvng/step02/xform-a.py z3/deliverance/sandboxes/paul/dvng/step02/xform.py z3/deliverance/sandboxes/paul/dvng/step03/ z3/deliverance/sandboxes/paul/dvng/step03.rst z3/deliverance/sandboxes/paul/dvng/step03/compiler.xsl z3/deliverance/sandboxes/paul/dvng/step03/content2.html z3/deliverance/sandboxes/paul/dvng/step03/dvfinalstage-a.xsl z3/deliverance/sandboxes/paul/dvng/step03/dvfinalstage-b.xsl z3/deliverance/sandboxes/paul/dvng/step03/rules.rng z3/deliverance/sandboxes/paul/dvng/step03/rules.xml z3/deliverance/sandboxes/paul/dvng/step03/theme2.html z3/deliverance/sandboxes/paul/dvng/step03/xform.py Log: Source code Added: z3/deliverance/sandboxes/paul/dvng/conf.py ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/conf.py Mon May 19 21:35:17 2008 @@ -0,0 +1,100 @@ +# -*- coding: utf-8 -*- +# +# Sample Stample documentation build configuration file, created by +# sphinx-quickstart on Sun May 11 11:35:19 2008. +# +# This file is execfile()d with the current directory set to its containing dir. +# +# The contents of this file are pickled, so don't put values in the namespace +# that aren't pickleable (module imports are okay, they're removed automatically). +# +# All configuration values have a default value; values that are commented out +# serve to show the default value. + +import sys, os + +# If your extensions are in another directory, add it here. If the directory +# is relative to the documentation root, use os.path.abspath to make it +# absolute, like shown here. +#sys.path.append(os.path.abspath('some/directory')) + +# General configuration +# --------------------- + +# Add any Sphinx extension module names here, as strings. They can be extensions +# coming with Sphinx (named 'sphinx.ext.*') or your custom ones. +#extensions = [] + +# Add any paths that contain templates here, relative to this directory. +templates_path = ['.templates'] + +# The suffix of source filenames. +source_suffix = '.rst' + +# The master toctree document. +master_doc = 'index' + +# General substitutions. +project = 'DVNG Walkthrough' +copyright = '2008, Paul Everitt' + +# The default replacements for |version| and |release|, also used in various +# other places throughout the built documents. +# +# The short X.Y version. +version = '0.0.0.1' +# The full version, including alpha/beta/rc tags. +release = '0.0.0.1' + +# There are two options for replacing |today|: either, you set today to some +# non-false value, then it is used: +#today = '' +# Else, today_fmt is used as the format for a strftime call. +today_fmt = '%B %d, %Y' + +# List of documents that shouldn't be included in the build. +#unused_docs = [] + +# List of directories, relative to source directories, that shouldn't be searched +# for source files. +#exclude_dirs = [] + +# If true, '()' will be appended to :func: etc. cross-reference text. +#add_function_parentheses = True + +# If true, the current module name will be prepended to all description +# unit titles (such as .. function::). +#add_module_names = True + +# If true, sectionauthor and moduleauthor directives will be shown in the +# output. They are ignored by default. +#show_authors = False + +# The name of the Pygments (syntax highlighting) style to use. +pygments_style = 'sphinx' + + +# Options for HTML output +# ----------------------- + +# The style sheet to use for HTML and HTML Help pages. A file of that name +# must exist either in Sphinx' static/ path, or in one of the custom paths +# given in html_static_path. +html_style = 'default.css' + +# The name for this set of Sphinx documents. If None, it defaults to +# " v documentation". +#html_title = None + +# The name of an image file (within the static path) to place at the top of +# the sidebar. +#html_logo = None + +# Add any paths that contain custom static files (such as style sheets) here, +# relative to this directory. They are copied after the builtin static files, +# so a file named "default.css" will overwrite the builtin "default.css". +#html_static_path = ['.static'] + +# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, +# using the given strftime format. +html_last_updated_fmt = '%b %d, %Y' Added: z3/deliverance/sandboxes/paul/dvng/index.rst ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/index.rst Mon May 19 21:35:17 2008 @@ -0,0 +1,70 @@ +=========================================== +DVNG - Rewriting the XSLT Renderer +=========================================== + +Deliverance is a simple system for applying a common look-and-feel to all +pages across site, no matter what system generated the pages. Currently, +Deliverance has two modes it uses to render: + + - The Python Renderer uses lxml to manipulate HTML node trees during a + request. This is the default renderer and the most supported. + + - The XSLT Renderer generates an XSLT stylesheet that is applied to the + content, transforming the content page into a themed result. For this + renderer, XSLT is nothing but an internal, intermediate language: + Deliverance integrators need never see a single line of XSLT. + +DVNG is an experiment in rewriting the XSLT Renderer to achieve some new +goals, while also prototyping the redesign of the Deliverance +specification. + +Design and Goals +------------------------ + +In a nutshell, DVNG uses a multistage approach to generate a standalone +XSLT stylesheet. The stages break the work into smaller, more easily +debugged chunks, using a combination of Pythonic lxml programming and +XSLT transformation to produce the final stage. + +This final stage can be run with any XSLT processor and is no longer tied +to the original theme, rules, or Deliverance processing logic. Stated +differently, the final stage could be checked into Subversion and used +without even installing Deliverance on a production server. + +The goals include: + +- *Speed*. The current Deliverance renderers do a lot of work on each + request. DVNG plans to do a lot of work once, with the result being + usable not just between requests, but for as long as the theme and + rules do not change. + +- *Reliability*. Much less complex. + +- *Debuggability*. + +- *Extensibility*. + +About This Document +--------------------------- + +This walkthrough is aimed first at the Deliverance mailing list, where we +are considering design of the new specification and implementations. + +As such, we'll gradually build the result, step by step, to show the +thinking that went into this approach. In some ways, this is an advocacy +document, meant not just to explain, but also to persuade. Apologies in +advance. (wink) + +Requirements +-------------------- + +Some of the work produced herein can run directly in Firefox 3.0b5+. +Others can be run with a fairly recent version of ``xsltproc``. For the +complete effect, though, you might want to install the Python lxml +extension, version 2.0 or higher. + +.. toctree:: + + step01.rst + step02.rst + step03.rst \ No newline at end of file Added: z3/deliverance/sandboxes/paul/dvng/step01.rst ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step01.rst Mon May 19 21:35:17 2008 @@ -0,0 +1,146 @@ +=========================================== +Step 01 - The Minimum +=========================================== + +We have a number of things to introduce for DVNG. So in this first step +we take it pretty easy: + +- View and explain the final step in the production of a "compiled + themeset" + +- See how to run that compiled themeset on a content page + +Sample Data and Desired Output +---------------------------------------- + +In this first step, we'll support a very simple case: taking a "page +heading" from the content and putting in the right box of the theme. + +For this step, imagine a very simple theme: + +.. literalinclude:: step01/theme.html + :language: html + :linenos: + +And a very simple content page: + +.. literalinclude:: step01/content.html + :language: html + :linenos: + +On line 6 of the theme, we want to replace the ``Theme Page Heading`` +text inside the ``

`` with the ``DVNG Walkthrough`` content from line +2 of the content page. That is, we want the following markup as the +themed result: + +.. literalinclude:: step01/result.html + :language: html + :linenos: + +Compilation +------------------ + +Under Deliverance, we would effect this transform by writing a rules +file and doing the Deliverance processing. + +For DVNG, though, let's invert the thinking: let's start at the end and +discuss what should the "final stage" XSLT look like? We can then work +the problem backwards, writing stages that gradually produce that +result, using the theme file and the rules file as the ultimate source. + +Here is an XSLT that prepares the way for later DVNG features: + +.. literalinclude:: step01/dvfinalstage.xsl + :language: xslt + :linenos: + +There are 3 major sections to this: + +#. *Compiled Theme*. Lines 4-19 handle the compiled theme, generated by + earlier stages of DVNG. We first make an ``xsl:variable`` that holds + the mixture of HTML (from the theme file) and XSLT instructions (by + way of the rules file). We then use EXSLT to turn this into a named + nodeset that we can do further work on. Note that, when the variable + is initialized, the XSLT instructions are processed and thus, the + theme processes the content. + +#. *Start processing*. Line 20 is the XSLT rule that matches on the top + of the incoming content page, and thus, the start of processing the + transform. This template rule is very simple: grab the first node in + the *compiled theme* (instead of the incoming content page), start + processing, and thus pass control over to other XSLT templates. + +#. *Identity transform*. Lines 25-28 are the classic XSLT pattern known + as the "identity transform." This least-common-denominator rule + matches when nothing else does, and simply copies the result to the + output, recursively. + +So in a nutshell: + +- At runtime, create a variable that holds the themed content. + +- Copy that content to the result document. + +Running +---------------- + +You can try this quite easily using ``xsltproc`` in the ``step01``:: + + $ /usr/bin/xsltproc dvfinalstage.xsl content.html + + + + Theme Page Title + + +

+ DVNG Walkthrough +

+

Some theme text here.

+ + + +You can also time the performance:: + + $ /usr/bin/xsltproc --repeat --timing dvfinalstage.xsl content.html + Parsing stylesheet dvfinalstage.xsl took 0 ms + Parsing document content.html took 0 ms + Applying stylesheet 20 times took 6 ms + + + + Theme Page Title + + +

+ DVNG Walkthrough +

+

Some theme text here.

+ + + +Additionally,here is a Python script that uses lxml to apply the result +to the content: + + +.. literalinclude:: step01/xform.py + :linenos: + +And finally, you can point Firefox (version 3.0b5 or later) or Safari at +the ``step01\content.xml``. It will transform the input using the XSLT +and let you view the results of your compiled themeset. + +.. note:: + + How did that work? Firefox (and IE, and Opera, and Safari) have long + supported client-side XSLT. You send back an XML document with a + "processing instruction" that points at a CSS or XSLT to help + visualize the XML. In the case of XSLT, the browser transforms the XML + document into HTML and shows the result. + + We had to copy the ``content.html`` to a ``content.xml`` to trick + Firefox/Safari into opening the file in XML mode. + + Why such a recent Firefox? Because this experiment relies on features + from the EXSLT extensions to XSLT, which are only recently supported + on Firefox. \ No newline at end of file Added: z3/deliverance/sandboxes/paul/dvng/step01/content.html ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step01/content.html Mon May 19 21:35:17 2008 @@ -0,0 +1,3 @@ +
+

DVNG Walkthrough

+
\ No newline at end of file Added: z3/deliverance/sandboxes/paul/dvng/step01/content.xml ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step01/content.xml Mon May 19 21:35:17 2008 @@ -0,0 +1,5 @@ + + +
+

DVNG Walkthrough

+
Added: z3/deliverance/sandboxes/paul/dvng/step01/dvfinalstage.xsl ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step01/dvfinalstage.xsl Mon May 19 21:35:17 2008 @@ -0,0 +1,30 @@ + + + + + + + Theme Page Title + + +

+ + +

+

Some theme text here.

+ + +
+ + + + + + + + + + +
Added: z3/deliverance/sandboxes/paul/dvng/step01/result.html ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step01/result.html Mon May 19 21:35:17 2008 @@ -0,0 +1,12 @@ + + + +Theme Page Title + + +

+ DVNG Walkthrough +

+

Some theme text here.

+ + Added: z3/deliverance/sandboxes/paul/dvng/step01/theme.html ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step01/theme.html Mon May 19 21:35:17 2008 @@ -0,0 +1,9 @@ + + + Theme Page Title + + +

Theme Page Heading

+

Some theme text here.

+ + \ No newline at end of file Added: z3/deliverance/sandboxes/paul/dvng/step01/xform.py ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step01/xform.py Mon May 19 21:35:17 2008 @@ -0,0 +1,11 @@ +from lxml import etree + +def main(): + contentdoc = etree.ElementTree(file="content.html") + xsldoc = etree.ElementTree(file="dvfinalstage.xsl") + processor = etree.XSLT(xsldoc) + result = processor(contentdoc) + print result + +if __name__ == "__main__": + main() Added: z3/deliverance/sandboxes/paul/dvng/step02.rst ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step02.rst Mon May 19 21:35:17 2008 @@ -0,0 +1,191 @@ +=========================================== +Step 02 - A "Compiler" for DVNG +=========================================== + +We saw in Step 01 how an XSLT could be produced that handled the simple +case. Before going into more complicated cases, though, let's work the +problem backwards. Remember, we want to start with the ``theme.html`` +file on disk with a ``rules.xml`` file lying around somewhere. + +In this step we'll work on: + +- An XSLT "compiler" that produces the ``dvfinalstage.xsl`` in Step 01 + +- An input document for that XSLT that is the theme file...with a little + help from lxml + +- And of course, the rules file + +Sample Data and Desired Output +---------------------------------------- + +We'll use the (almost) same ``theme.html`` and ``content.html`` files +from Step 01. Additionally, we want to use the beginnings of a rules +file: + +.. literalinclude:: step02/rules.xml + :language: xml + :linenos: + +This is the minimum to express our goal, which is to keep everything in +the theme but replace the theme's "pageheading" text with text from the +content page. We'll add other rules and more rule attributes later. + +Regarding the desired output, this is simple: we want this stage to +produce the ``dvfinalstage.xsl`` as shown in Step 01. Again, once we +have that XSLT, we can use it anywhere that supports XSLT processing +(albeit with EXSLT extensions.) + +Overview and theme "hints" +------------------------------- + +Our strategy in this stage goes a little bit like this: + +- Start with a "hinted" theme file (explained next) + +- Have a `compiler.xsl` that converts the theme file into the final + stage + +- This compiler.xsl also reads in the rules file + +This stage expects the theme file to have some "hints" in it. Namely, we +expect an earlier stage to have found and marked the nodes in the theme +that were matched by a rule's @themeid attribute. As an example:: + +

Theme + Page Heading

+ +This adds two attributes to the spot in the theme where a rule should +operate: + +- dv:ruleid points to the rule number (position()) that matched this + theme node + +- dv:ruletype indicates what kind of rule (append, prepend, etc.) was + matched. The reason for this will be explained when we look at the + compiler. + +Compilation +---------------------- + +Now let's take a look at the "compiler", which is nothing more than an +XSLT: + +.. literalinclude:: step02/compiler.xsl + :language: xslt + :linenos: + +Walking through the thinking of the compiler: + +#. **Lines 2-5**. Lots of namespaces in here. These point to extended + functionality from the EXSLT (exslt.org) standard add-ons. Also, we + need a trick to make it easy to generate XSLT nodes in the output + without interpreting them as part of the transform. namespace-alias, + in combination with binding the processing to the "x:" prefix, does + this. + +#. **Line 7**. Read the rules file in as an input document in addition + to the ``theme.html`` that will be the regular input document. + +#. **Lines 9-24**. Generate most of the boilerplate for the desired + output, which is the ``dvfinalstage.xsl`` in Step 01. + +#. **Line 12**. Pass control back to the XSLT processor, which starts + recursively processing all the nodes in the input document + (theme.html), looking for rules to match. + +#. **Lines 25-34**. Ah *HA*! The heart of the matter. Match on an HTML + node in the theme that has those funny hints. In this case, handle a + case where we are supposed to do a Deliverance "replace". This is, + essentially, the implementation of a Deliverance "rule". + +#. **Line 27**. Copy all the attributes from the theme node to the + output, *except* those funny "hint" attributes in the ``dv:`` + namespace. + +#. **Lines 28-32**. The ``replace`` rule says to take out all the theme + node's children and insert all the nodes matched in the content. This + maps to an ```` expression, so + create one of those. Use a convenience function (``dv:getrule()``, + explained next) to grab the rule's ``@content`` attribute for the + value of "somexpath". + +#. **Lines 35-37**. Define an extension function to make it easy to find + the rule that placed the hints in the theme node. + +Running +---------------- + +Again, you can try this quite easily using ``xsltproc`` in the +``step02`` directory. Remember to run it against the ``theme.html`` +document:: + + $ /usr/bin/xsltproc dvfinalstage.xsl theme.html + + + + + + Theme Page Title + + +

+ + +
+ + + + + + + + + +
+ +You can run this in, save to a file, and then run the final stage:: + + $ /usr/bin/xsltproc compiler.xsl theme.html > dvfinalstage.xsl + $ /usr/bin/xsltproc dvfinalstage.xsl content.html + + + + Theme Page Title + + +

DVNG Walkthrough

+

Some theme text here.

+ + + +This is the output we expected: the ``

`` gets its value from the +content page instead of the theme. + +Python For First Stage +------------------------------ + +We will start with a Python file that does the same work as the +``xsltproc`` example: + +.. literalinclude:: step02/xform-a.py + :language: python + :linenos: + +This example uses a small class, instead of one big function. + +Next up, we need to add the logic that produces the "hints" in the +theme. Just for fun, we turn the result of the first stage into the +final processor and use it to theme some content: + +.. literalinclude:: step02/xform.py + :language: python + :linenos: + +This has plenty of docstrings and comments, but let's walk through the +lines: + +#. **Line 4-6**. Setup some XML namespace-oriented constants. Added: z3/deliverance/sandboxes/paul/dvng/step02/compiler.xsl ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step02/compiler.xsl Mon May 19 21:35:17 2008 @@ -0,0 +1,43 @@ + + + + + + http://openplans.org/deliverance + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Added: z3/deliverance/sandboxes/paul/dvng/step02/content.html ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step02/content.html Mon May 19 21:35:17 2008 @@ -0,0 +1,3 @@ +
+

DVNG Walkthrough

+
\ No newline at end of file Added: z3/deliverance/sandboxes/paul/dvng/step02/dvfinalstage.xsl ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step02/dvfinalstage.xsl Mon May 19 21:35:17 2008 @@ -0,0 +1,24 @@ + + + + + + Theme Page Title + + +

+

Some theme text here.

+ + +
+ + + + + + + + + +
+ Added: z3/deliverance/sandboxes/paul/dvng/step02/rules.xml ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step02/rules.xml Mon May 19 21:35:17 2008 @@ -0,0 +1,6 @@ + + + + Added: z3/deliverance/sandboxes/paul/dvng/step02/theme.html ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step02/theme.html Mon May 19 21:35:17 2008 @@ -0,0 +1,9 @@ + + + Theme Page Title + + +

Theme Page Heading

+

Some theme text here.

+ + \ No newline at end of file Added: z3/deliverance/sandboxes/paul/dvng/step02/xform-a.py ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step02/xform-a.py Mon May 19 21:35:17 2008 @@ -0,0 +1,20 @@ +from lxml import etree + +class DVNG: + + def __init__(self): + self.compilerdoc = etree.ElementTree(file="compiler.xsl") + self.compiler = etree.XSLT(self.compilerdoc) + + def __call__(self, themefn): + themedoc = etree.ElementTree(file=themefn) + result = self.compiler(themedoc) + return result + +def main(): + dvng = DVNG() + result = dvng("theme.html") + print result + +if __name__ == "__main__": + main() Added: z3/deliverance/sandboxes/paul/dvng/step02/xform.py ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step02/xform.py Mon May 19 21:35:17 2008 @@ -0,0 +1,54 @@ +from lxml import etree + +# Constants +DV_NAMESPACE = "http://openplans.org/deliverance" +DV = "{%s}" % DV_NAMESPACE +NSMAP = {"dv": DV_NAMESPACE} + +class DVNG: + + compilerfn = "compiler.xsl" + + def compileTheme(self, themefn, rulesfn): + """Given theme and rule files, make a compiled themeset""" + + # Make the compiler XSLT + compilerdoc = etree.ElementTree(file=self.compilerfn) + compiler = etree.XSLT(compilerdoc) + + # Load the theme doc and rules doc + self.themedoc = etree.ElementTree(file=themefn) + self.rulesdoc = etree.ElementTree(file="rules.xml") + + # Iterate over the rules, find the theme nodes that + # match, and add the "hint" attributes. + position = 1 + for rule in self.rulesdoc.xpath("/*/*", namespaces=NSMAP): + themexpath = rule.get("theme") + ruletype = rule.tag.split("}")[1] + for themenode in self.themedoc.xpath(themexpath): + themenode.set(DV + "ruleid", str(position)) + themenode.set(DV + "ruletype", ruletype) + position = position +1 + + # themedoc now hacked to provide hints, so transform. + self.finalstage = compiler(self.themedoc) + self.processor = etree.XSLT(self.finalstage) + + def __call__(self, contentfn): + """Apply a compiled themeset against a contentdoc""" + + # Turn the result into a processor + content = etree.ElementTree(file=contentfn) + result = self.processor(content) + + return result + +def main(): + dvng = DVNG() + dvng.compileTheme("../step01/theme.html", "rules.xml") + result = dvng("../step01/content.html") + return result + +if __name__ == "__main__": + print main() Added: z3/deliverance/sandboxes/paul/dvng/step03.rst ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step03.rst Mon May 19 21:35:17 2008 @@ -0,0 +1,291 @@ +=========================================== +Step 03 - Multi-theme support +=========================================== + +We've come quite a way so far. Although only for one kind of theme rule, +we have support for processing a theme and rule file, then applying the +theme to a content page. + +DVNG, though, can serve as a way to investigate new capabilities for +Deliverance. Theming different pages in different ways is one of the +biggest points under consideration for Deliverance. In this step +investigate it: + +- Support theme switching in the ``dvfinalstage.xsl`` compiled themeset + +- Extend the compiler to support a rules file that specifies themes and + conditions + +- Provide rich information from the environment, such as HTTP headers, + for theme switching + +To do this, we'll gradually build up the support working backwards from +the "compiled themeset". + +Sample Data and Desired Output +---------------------------------------- + +For our main theme, we'll continue using ``step01/theme.html``. We'll +leave the file in that directory, as well as ``step01/content.html`` as +an example of a content page that should be styled with that theme. + +We'll also introduce a second theme, one that includes a table layout +with a left-column navigation: + +.. literalinclude:: step03/theme2.html + :language: html + :linenos: + +We will use ``step03/content2.html`` to represent a content page that +should be themed with Theme 2. + +.. literalinclude:: step03/content2.html + :language: html + :linenos: + +This is a very different content page: + +- It looks more like a full HTML page, with an ```` root node + +- It's more semantic-oriented: the ```` is in the ``<title>``, + not also repeated as an ``<h1>`` in the ``<body>``. + +- There is some document-ish content in the ``<body>``. + +- And key to our scenario, we pack in some information about the + "section" that the content page occurs in, as a ``<meta>`` element in + the ``<head>``. We'll use this to use a different theme, one for + subordinate pages. + +For the desired output, we want the first theme to do as before, but +also take the ``<title>`` from the content page. The second theme, +though, should do a bit more: + +- Merge the content's ``<title>`` into both the ``<title>`` of the + themed result and the ``<h1>`` heading + +- Copy everything from the ``<body>`` of the content into the + "pagecontent" of the themed result + + +Compiled Themeset +----------------------- + +As before, the goal is to have an XSLT transform that is self-contained +and can be used in any context that supports applying XSLT +transformations. + +Using ``step01/dvfinalstage.xsl`` as the starting point, let's add +support for multiple themes. First up: + +.. literalinclude:: step03/dvfinalstage-a.xsl + :language: xslt + :linenos: + +#. **Lines 4-49**. Bind a theme to a variable. + +#. **Line 7**. The key to multitheme: use ``<xsl:choose>`` to select + which theme to bind to the variable. In this case, if the content + page has a ``<meta>`` tag named ``dv.section``, then use the theme + in that ``<xsl:when>``. + +#. **Line 33**. If nothing else matches, use the final theme. + +Everything else in the compiled theme is the same as in Step 01. + + +Running Part A +------------------- + +We now have support in the final stage for multiple themes. How can we +run it? Same as before:: + + $ xsltproc dvfinalstage-a.xsl content2.html + <html> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"> + <title>A Deeper Look At DVNG + + + + +

Navigation

+

A Deeper Look At DVNG

+
+

I have some content in here to merge.

+

Perhaps an image will be in here later.

+
+
+ + + $ xsltproc dvfinalstage-a.xsl ../step01/content.html + + + + DVNG Walkthrough + + +

DVNG Walkthrough

+

Some theme text here.

+ + + +As you can see, the content in the first page (the ```` tag) +triggers the table-based theme. The performance is the same: 20 +transforms in 7 milliseconds. + + +Theme Choice From Other Data +------------------------------------- + +In this first case, we chose the theme based on information *in* the +content page. But what if we want to choose from information in the URL, +an HTTP header such as the content type, etc.? + +We'll add support for this in a relatively simple way: using XSLT +*parameters*, or arguments the XSLT processor can supply to the +transform. At the top of ``step03/dvfinalstage-b.xsl`` we see:: + + look-at-me.com + +This "declares" a transformation parameter and assigns a default value. + +.. note:: + + The ``req`` sure looks a lot like WebOb, right? Yes, the idea is + to match the documentation for WebOb and have it able to + supply values easily as parameters. In this case, ``domain_url`` + isn't something provided by WebOb (as it isn't part of the + WSGI spec). Perhaps we can add it to WebOb. + + Also, note that use of parameters places more work on the + XSLT environment that will apply the stylesheet. Use of + this feature (themeswitching based on the environment instead + of content) likely means a compiled themeset that only works + in Deliverance. + +The test condition on line 8 then changes. Instead choosing a template +based on nodes in the content page, we choose content based on the value +of the parameter:: + + + +How will we implement this? That's the topic of the next section, but in +summary: + +- The rules file will indicate where a certain condition will match + +- Based on what the rules file asks for, the ``compiler.xsl`` will put + ```` declarations in the compiled themeset + (``dvfinalstage.xsl``) + +- During operation, an XSLT processor will be expected to pass values to + this parameter to change the default value on a per-request basis + +You can run this with ``xsltproc`` as follows:: + + $ xsltproc --stringparam req.domain_url foo.com dvfinalstage-b.xsl content2.html + +The ``--stringparam`` is a way to pass a parameter value on the +commandline. In lxml you pass keyword parameters to the ``XSLT()`` +function, as we'll see in the next section. + + +Rulefile Support For Theme Switching +-------------------------------------------- + +We want theme switching to be declarative. We don't want Deliverance +users to express it in Python and we definitely don't want them to +express it in XSLT. + +That means support in the ``rules.xml`` file. For example: + +.. literalinclude:: step03/rules.xml + :language: xml + :linenos: + +The rules file has more features now: + +#. **Line 1**. We wrap everything in a ```` to contain + each defined theme. + +#. **Lines 4-15**. A ```` contains an ``@href`` pointing to + the HTML file, a ```` which defines any of the conditions + to which this applies, and a ```` which contains the + Deliverance rules. Note that precedence matters: the first + ```` containing a ```` that matches will be + triggered. + +#. **Line 7-8**. If the content contains a ```` tag of + ``dv.section`` **OR** there the ``Request`` has a ``domain_url`` + value equal to ``look-at-me.com``, then use this theme. Note: + we can map to XPath string functions such as contains, + starts-with, and substring if we find a suitable expression + language. + +#. **Lines 10-14**. The rules, as before. + +#. **Lines 16-22**. This last theme has no ```` (which + is optional), indicating that this is to be used when nothing + else matches. + +Note also that we have added support for a minimal Relax NG schema that +helps us validate our rules file. This is particularly helpful for tools +(such as oXygen, which inserted that second line that references the +schema) that do autocomplete, element documentation via the schema, and +validate-as-you-type. + +Compiling the New Rule File +----------------------------------- + +As in Step 02, we need a Python module which, given the theme files and +the rules file, will generate the final stage XSLT. + +Along the way we'll make some changes to the Step 02 ``xform.py`` to +make it more flexible: + +- Presume that the ``compiler.xsl`` is in the same directory as the + ``xform.py``. + +- Merge the rules and all themes into a single input document. + +- Let the ``theme/@href`` values define the location of the theme with + support for the ``here`` keyword. + +- Pass the location of the content file to be themed as a command-line + argument. + +- Load the content page using the HTML parser, in case it is messy. + +- Provide debug support to write to disk all the intermediate stages. + +This leads to a very different strategy for the Python module and the +``compiler.xsl``. Let's start with the new Python module: + +.. literalinclude:: step03/xform.py + :language: python + :linenos: + +Here is the new compiler file: + +.. literalinclude:: step03/compiler.xsl + :language: xslt + :linenos: + +Running the module against one of the sample content pages is easy:: + + $ python ./xform.py content2.html + + + + Second Theme Page Title + + + + +

Navigation

+

A Deeper Look At DVNG

+
Theme content to replace.
+
+ + Added: z3/deliverance/sandboxes/paul/dvng/step03/compiler.xsl ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step03/compiler.xsl Mon May 19 21:35:17 2008 @@ -0,0 +1,103 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + or + + + + + + + + + + + + + + + + $req.='' + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Added: z3/deliverance/sandboxes/paul/dvng/step03/content2.html ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step03/content2.html Mon May 19 21:35:17 2008 @@ -0,0 +1,10 @@ + + + A Deeper Look At DVNG + + + +

I have some content in here to merge.

+

Perhaps an image will be in here later.

+ + Added: z3/deliverance/sandboxes/paul/dvng/step03/dvfinalstage-a.xsl ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step03/dvfinalstage-a.xsl Mon May 19 21:35:17 2008 @@ -0,0 +1,61 @@ + + + + + + + + + + <xsl:value-of select="/html/head/title"/> + + + + + + + + +
+

Navigation

+
+

+ +

+
+ +
+
+ + +
+ + + + + <xsl:value-of select="/div[@id='page-content']/h1"/> + + + +

+ +

+

Some theme text here.

+ + +
+
+
+ + + + + + + + + + +
Added: z3/deliverance/sandboxes/paul/dvng/step03/dvfinalstage-b.xsl ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step03/dvfinalstage-b.xsl Mon May 19 21:35:17 2008 @@ -0,0 +1,62 @@ + + + look-at-me.com + + + + + + + + <xsl:value-of select="/html/head/title"/> + + + + + + + + +
+

Navigation

+
+

+ +

+
+ +
+
+ + +
+ + + + + <xsl:value-of select="/div[@id='page-content']/h1"/> + + + +

+ +

+

Some theme text here.

+ + +
+
+
+ + + + + + + + + + +
Added: z3/deliverance/sandboxes/paul/dvng/step03/rules.rng ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step03/rules.rng Mon May 19 21:35:17 2008 @@ -0,0 +1,41 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file Added: z3/deliverance/sandboxes/paul/dvng/step03/rules.xml ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step03/rules.xml Mon May 19 21:35:17 2008 @@ -0,0 +1,22 @@ + + + + + + /html/head/meta[@name='dv.section'] + look-at-me.com + + + + + + + + + + + \ No newline at end of file Added: z3/deliverance/sandboxes/paul/dvng/step03/theme2.html ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step03/theme2.html Mon May 19 21:35:17 2008 @@ -0,0 +1,18 @@ + + + Second Theme Page Title + + + + + + + +
+

Navigation

+
+

Theme Page Heading

+
Theme content to replace.
+
+ + Added: z3/deliverance/sandboxes/paul/dvng/step03/xform.py ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step03/xform.py Mon May 19 21:35:17 2008 @@ -0,0 +1,134 @@ +import lxml.html +from lxml import etree +import os +import sys + +# Constants +DV_NAMESPACE = "http://openplans.org/deliverance" +DV = "{%s}" % DV_NAMESPACE +NSMAP = {"dv": DV_NAMESPACE} + +class DVNG: + + def __init__(self, heredir, rulesuri): + + # Some paths and filenames + self.heredir = heredir + absdir = os.path.dirname(os.path.abspath(__file__)) + self.compilerfn = os.path.join(absdir, "compiler.xsl") + + # Make the compiler XSLT + self.compilerdoc = etree.ElementTree(file=self.compilerfn) + self.compiler = etree.XSLT(self.compilerdoc) + + # Load the rules doc then the theme docs. We want + # both the original (for later introspection), plus + # a "compiled rules" which will act as the input document + # for the compilation transform. + self.origrulesdoc = etree.ElementTree(file=rulesuri) + self.cr = etree.ElementTree(file=rulesuri) + + # Add hints and load HTML source + self._makeRuleIds() + self._loadThemes() + + # Themes now hacked to provide hints, so transform. + self.finalstage = self.compiler(self.cr) + self.processor = etree.XSLT(self.finalstage) + + def __call__(self, contentfn): + """Apply a compiled themeset against a contentdoc""" + + # Turn the result into a processor + content = etree.ElementTree(file=contentfn) + kw = {'req.domain_url': 'look-at-me.com'} + result = self.processor(content, **kw) + + return result + + + def _loadThemes(self): + + # First, find all the nodes, + # retrieve the HTML, process it, and merge into the + # compiled rules file. + + for themeuri in self._getNode("/dv:themeset/dv:theme/@href"): + # Grab the dv:theme node, then its dv:match child + themenode = themeuri.getparent() + match = themenode.find(DV + "match") + + # Make nice URI to theme source HTML and retrieve + parturi = self._expandURI(themeuri) + themehtml = lxml.html.parse(parturi).getroot() + + # Find all theme nodes referenced by rules and put in + # hints + self._makeThemeHints(themehtml, themenode) + + # Graft in the hinted HTML source into the compiled rules + themesource = etree.SubElement(themenode, DV + "source") + themesource.append(themehtml) + + def _makeThemeHints(self, htmlroot, themenode): + """Given raw HTML, add @ruleid and @ruletype to correct nodes""" + + for themexpath in self._getNode("dv:rules/*/@theme", themenode): + ruleid = themexpath.getparent().get("id") + ruletype = themexpath.getparent().tag.split("}")[1] + themenode = htmlroot.xpath(themexpath)[0] + themenode.set("ruleid", ruleid) + themenode.set("ruletype", ruletype) + + + def _makeRuleIds(self): + """Put identifiers in rules to use as a primary key""" + + rulenum = 0 + for rule in self._getNode("/dv:themeset/dv:theme/dv:rules/*"): + rulenum = rulenum + 1 + ruleid = "r%s" % rulenum + rule.set("id", ruleid) + + + def _getNode(self, xp, node=None): + """Easier way to get namespaced XPaths on compiled rules doc""" + + if node is None: + # Allow passing a different starting point + node = self.cr + + return node.xpath(xp, namespaces=NSMAP) + + + def _expandURI(self, themeuri): + """Given a file:///%(here)s URI, return a usable reference""" + + fulluri = themeuri % {'here': self.heredir} + return fulluri[7:] # Cheat, as lxml.html can't do file:/// + + def debug(self): + """Write out key artifacts to disk""" + + self._writeDoc(self.cr, "cr.xml") + self._writeDoc(self.finalstage, "finalstage.xsl") + + + def _writeDoc(self, doc, filename): + + f = open("xxx-%s" % filename, "w") + f.write(etree.tostring(doc, pretty_print=True)) + f.close() + + +def main(): + moduledir = os.path.dirname(os.path.abspath(__file__)) + heredir = os.path.dirname(moduledir)[1:] + dvng = DVNG(heredir, "rules.xml") + dvng.debug() + result = dvng(sys.argv[1]) + return result + +if __name__ == "__main__": + result = main() + print result \ No newline at end of file From paul at codespeak.net Mon May 19 21:35:44 2008 From: paul at codespeak.net (paul at codespeak.net) Date: Mon, 19 May 2008 21:35:44 +0200 (CEST) Subject: [z3-checkins] r54963 - z3/deliverance/sandboxes/paul/dvng/step01 Message-ID: <20080519193544.04B31168540@codespeak.net> Author: paul Date: Mon May 19 21:35:43 2008 New Revision: 54963 Modified: z3/deliverance/sandboxes/paul/dvng/step01/dvfinalstage.xsl (props changed) Log: Source code From ianb at codespeak.net Mon May 19 23:02:14 2008 From: ianb at codespeak.net (ianb at codespeak.net) Date: Mon, 19 May 2008 23:02:14 +0200 (CEST) Subject: [z3-checkins] r54964 - in z3/deliverance/trunk: . deliverance deliverance/test-data Message-ID: <20080519210214.CCEF716852A@codespeak.net> Author: ianb Date: Mon May 19 23:02:11 2008 New Revision: 54964 Modified: z3/deliverance/trunk/CHANGES.txt z3/deliverance/trunk/deliverance/interpreter.py z3/deliverance/trunk/deliverance/test-data/test_move.xml z3/deliverance/trunk/deliverance/xslt.py Log: Run all rules in order (previously drop and move rules ran before other rules; deprecate the XSLT renderer, which could not implement in-order rules Modified: z3/deliverance/trunk/CHANGES.txt ============================================================================== --- z3/deliverance/trunk/CHANGES.txt (original) +++ z3/deliverance/trunk/CHANGES.txt Mon May 19 23:02:11 2008 @@ -25,6 +25,14 @@ - (setup) Relax restriction on lxml 2.x (which should work fine). +- (interpreter) Run the rules in order, including running drop rules + in order (previously they were always run before all other rules) + and run move="1" rules in order with all the other rules. + +- Deprecate the XSLT interpreter. Changing rules to run in order was + not feasible with the XSLT version, but the intuitive behavior was + more important than the alternate renderer. + 0.1.2 (2008-02-19) ------------------ Modified: z3/deliverance/trunk/deliverance/interpreter.py ============================================================================== --- z3/deliverance/trunk/deliverance/interpreter.py (original) +++ z3/deliverance/trunk/deliverance/interpreter.py Mon May 19 23:02:11 2008 @@ -78,22 +78,9 @@ rules, theme and content should be lxml etree structures. """ - drop_rules, other_rules = self.separate_drop_rules(rules) - move_rules, other_rules = self.separate_move_rules(other_rules) - - # process all drop rules first - for rule in drop_rules: - self.apply_rule(rule, theme, content) - - # process all move rules next - for rule in move_rules: - self.apply_rule(rule,theme,content) - - # finally the rest - for rule in other_rules: + for rule in rules: self.apply_rule(rule, theme, content) - def apply_rule(self, rule, theme, content): """ calls proper rule application function for Modified: z3/deliverance/trunk/deliverance/test-data/test_move.xml ============================================================================== --- z3/deliverance/trunk/deliverance/test-data/test_move.xml (original) +++ z3/deliverance/trunk/deliverance/test-data/test_move.xml Mon May 19 23:02:11 2008 @@ -5,8 +5,8 @@ - + @@ -98,8 +98,8 @@ - + @@ -142,8 +142,8 @@ - + Modified: z3/deliverance/trunk/deliverance/xslt.py ============================================================================== --- z3/deliverance/trunk/deliverance/xslt.py (original) +++ z3/deliverance/trunk/deliverance/xslt.py Mon May 19 23:02:11 2008 @@ -67,6 +67,8 @@ before being returned. """ + import warnings + warnings.warn("The XSLT renderer is deprecated; please use deliverance.interpreter.Renderer instead. The XSLT renderer may produce different results than the Python renderer", DeprecationWarning) theme_copy = copy.deepcopy(theme) self.rules = rule self.rules_uri = rule_uri From paul at codespeak.net Mon May 19 23:47:46 2008 From: paul at codespeak.net (paul at codespeak.net) Date: Mon, 19 May 2008 23:47:46 +0200 (CEST) Subject: [z3-checkins] r54965 - z3/deliverance/sandboxes/paul/dvng/step03 Message-ID: <20080519214746.D7363168533@codespeak.net> Author: paul Date: Mon May 19 23:47:45 2008 New Revision: 54965 Added: z3/deliverance/sandboxes/paul/dvng/step03/content2.xml (contents, props changed) z3/deliverance/sandboxes/paul/dvng/step03/dvfinalstage.xsl (contents, props changed) Log: More properties Added: z3/deliverance/sandboxes/paul/dvng/step03/content2.xml ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step03/content2.xml Mon May 19 23:47:45 2008 @@ -0,0 +1,12 @@ + + + + + A Deeper Look At DVNG + + + +

I have some content in here to merge.

+

Perhaps an image will be in here later.

+ + Added: z3/deliverance/sandboxes/paul/dvng/step03/dvfinalstage.xsl ============================================================================== --- (empty file) +++ z3/deliverance/sandboxes/paul/dvng/step03/dvfinalstage.xsl Mon May 19 23:47:45 2008 @@ -0,0 +1,43 @@ + + look-at-me.com + + + + + + Second Theme Page Title + + + + +
+

Navigation

+
+

+
Theme content to replace.
+
+ +
+ + + + Theme Page Title + + +

+

Some theme text here.

+ + +
+
+
+ + + + + + + + + +
From magicbronson at codespeak.net Tue May 20 00:30:10 2008 From: magicbronson at codespeak.net (magicbronson at codespeak.net) Date: Tue, 20 May 2008 00:30:10 +0200 (CEST) Subject: [z3-checkins] r54979 - in z3/deliverance/DeliveranceVHoster/trunk: . dvhoster Message-ID: <20080519223010.17B6D168536@codespeak.net> Author: magicbronson Date: Tue May 20 00:30:09 2008 New Revision: 54979 Modified: z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dispatcher.py z3/deliverance/DeliveranceVHoster/trunk/dvhoster/model.py z3/deliverance/DeliveranceVHoster/trunk/fassembler_config.ini_tmpl Log: Added a default_rules_dir option that is searched for rules after the host-specific rules. No longer write out a default rules.xml file, relying instead on the default_rules_dir files to serve as a starting point. Modified: z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dispatcher.py ============================================================================== --- z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dispatcher.py (original) +++ z3/deliverance/DeliveranceVHoster/trunk/dvhoster/dispatcher.py Tue May 20 00:30:09 2008 @@ -4,6 +4,7 @@ from paste.request import path_info_pop, construct_url from paste import httpexceptions from paste.urlparser import StaticURLParser +from paste.cascade import Cascade from paste.fileapp import FileApp from paste.deploy.converters import asbool from wsgifilter import proxyapp @@ -61,6 +62,10 @@ logger = make_logger(app_conf.get('logger'), 'dvhoster') self.logger = logger + + self.default_rules = app_conf.get('default_rules_dir', + os.path.join(data_dir, 'default_rules')) + self.default_rules_app = StaticURLParser(self.default_rules) def __call__(self, environ, start_response): """ @@ -86,8 +91,9 @@ if path_info.startswith('/_rules'): path_info_pop(environ) environ['QUERY_STRING'] = '' - subapp = StaticURLParser( - domain_info.rule_dir) + print 'cascading applications in', domain_info.rule_dir, self.default_rules + subapp = Cascade([StaticURLParser(domain_info.rule_dir), + self.default_rules_app]) return subapp(environ, start_response) static_app = self.find_static_file(domain_info, path_info) Modified: z3/deliverance/DeliveranceVHoster/trunk/dvhoster/model.py ============================================================================== --- z3/deliverance/DeliveranceVHoster/trunk/dvhoster/model.py (original) +++ z3/deliverance/DeliveranceVHoster/trunk/dvhoster/model.py Tue May 20 00:30:09 2008 @@ -13,26 +13,6 @@ domain_re = re.compile(r'^[a-z][a-z0-9-]+|[a-z][a-z0-9.\-]+\.[a-z]+$', re.I) -default_rule_xml = '''\ - - - - - - -''' - -marker = '' -abstract_rule_xml = '''\ - -MARKER - - - - - -'''.replace('MARKER', marker) - default_standardrules = '''\ @@ -207,14 +187,6 @@ self.static_dir]: if not os.path.exists(dir): os.mkdir(dir) - for filename, content in [ - ('rule.xml', default_rule_xml), - ('standardrules.xml', default_standardrules)]: - filename = os.path.join(self.rule_dir, filename) - if not os.path.exists(filename): - f = open(filename, 'w') - f.write(content) - f.close() @property def initialized(self): Modified: z3/deliverance/DeliveranceVHoster/trunk/fassembler_config.ini_tmpl ============================================================================== --- z3/deliverance/DeliveranceVHoster/trunk/fassembler_config.ini_tmpl (original) +++ z3/deliverance/DeliveranceVHoster/trunk/fassembler_config.ini_tmpl Tue May 20 00:30:09 2008 @@ -77,6 +77,9 @@ # This is at least better than the old fallback of hitting openplans.org. default_theme_uri = {{project.req_settings.get('default_theme_uri', '/theme.html')}} +# Deliverance will look for rules in this directory if a host-specific +# rule is not found. +default_rules_dir = {{env.var}}/deliverance/default_rules # Specifies whether to load authentication middleware auth_enabled = True From paul at codespeak.net Tue May 20 02:40:45 2008 From: paul at codespeak.net (paul at codespeak.net) Date: Tue, 20 May 2008 02:40:45 +0200 (CEST) Subject: [z3-checkins] r54980 - in z3/deliverance/sandboxes/paul: docs docs/_sources dvng dvng/step02 dvng/step03 Message-ID: <20080520004045.D725716853F@codespeak.net> Author: paul Date: Tue May 20 02:40:43 2008 New Revision: 54980 Added: z3/deliverance/sandboxes/paul/dvng/step02/content.xml (contents, props changed) Modified: z3/deliverance/sandboxes/paul/docs/_sources/index.txt z3/deliverance/sandboxes/paul/docs/_sources/step02.txt z3/deliverance/sandboxes/paul/docs/_sources/step03.txt z3/deliverance/sandboxes/paul/docs/index.html z3/deliverance/sandboxes/paul/docs/searchindex.json z3/deliverance/sandboxes/paul/docs/step02.html z3/deliverance/sandboxes/paul/docs/step03.html z3/deliverance/sandboxes/paul/dvng/index.rst z3/deliverance/sandboxes/paul/dvng/step02.rst z3/deliverance/sandboxes/paul/dvng/step02/dvfinalstage.xsl (props changed) z3/deliverance/sandboxes/paul/dvng/step03.rst z3/deliverance/sandboxes/paul/dvng/step03/compiler.xsl Log: Fix inconsistencies Modified: z3/deliverance/sandboxes/paul/docs/_sources/index.txt ============================================================================== --- z3/deliverance/sandboxes/paul/docs/_sources/index.txt (original) +++ z3/deliverance/sandboxes/paul/docs/_sources/index.txt Tue May 20 02:40:43 2008 @@ -2,17 +2,18 @@ DVNG - Rewriting the XSLT Renderer =========================================== -Deliverance is a simple system for applying a common look-and-feel to all -pages across site, no matter what system generated the pages. Currently, -Deliverance has two modes it uses to render: +Deliverance is a simple system for applying a common look-and-feel to +all pages across a site, no matter what system generated the pages. +Currently, Deliverance has two modes it uses to render: - The Python Renderer uses lxml to manipulate HTML node trees during a request. This is the default renderer and the most supported. - - The XSLT Renderer generates an XSLT stylesheet that is applied to the - content, transforming the content page into a themed result. For this - renderer, XSLT is nothing but an internal, intermediate language: - Deliverance integrators need never see a single line of XSLT. + - The XSLT Renderer generates an XSLT stylesheet that is applied to + the content, transforming the content page into a themed result. For + this renderer, XSLT is nothing but an internal, intermediate + language: Deliverance integrators need never see a single line of + XSLT. DVNG is an experiment in rewriting the XSLT Renderer to achieve some new goals, while also prototyping the redesign of the Deliverance @@ -26,10 +27,10 @@ debugged chunks, using a combination of Pythonic lxml programming and XSLT transformation to produce the final stage. -This final stage can be run with any XSLT processor and is no longer tied -to the original theme, rules, or Deliverance processing logic. Stated -differently, the final stage could be checked into Subversion and used -without even installing Deliverance on a production server. +This final stage can be run with any XSLT processor and is no longer +tied to the original theme, rules, or Deliverance processing logic. +Stated differently, the final stage could be checked into Subversion and +used without even installing Deliverance on a production server. The goals include: @@ -38,17 +39,22 @@ usable not just between requests, but for as long as the theme and rules do not change. -- *Reliability*. Much less complex. +- *Reliability*. The production renderer is much less complex. -- *Debuggability*. - -- *Extensibility*. +- *Debuggability*. By making each stage of the rendering introspectable + in a "view source" fashion, you get some of the benefits of a + pipeline. Namely, you know what part of the process broke down. + +- *Extensibility*. Custom Deliverance rules, and even full-scale + extensions via imported XSLT, provide ways to make specialized changes + to the themes, rules, or even incoming content. All without adding + more features to Deliverance. About This Document --------------------------- -This walkthrough is aimed first at the Deliverance mailing list, where we -are considering design of the new specification and implementations. +This walkthrough is aimed first at the Deliverance mailing list, where +we are considering design of the new specification and implementations. As such, we'll gradually build the result, step by step, to show the thinking that went into this approach. In some ways, this is an advocacy Modified: z3/deliverance/sandboxes/paul/docs/_sources/step02.txt ============================================================================== --- z3/deliverance/sandboxes/paul/docs/_sources/step02.txt (original) +++ z3/deliverance/sandboxes/paul/docs/_sources/step02.txt Tue May 20 02:40:43 2008 @@ -50,7 +50,10 @@ This stage expects the theme file to have some "hints" in it. Namely, we expect an earlier stage to have found and marked the nodes in the theme -that were matched by a rule's @themeid attribute. As an example:: +that were matched by a rule's @themeid attribute. This serves the DVNG +goal of simplification: break work into smaller, simpler chunks. + +As an example::

Theme Page Heading

@@ -165,6 +168,11 @@ This is the output we expected: the ``

`` gets its value from the content page instead of the theme. +Finally, you can open `an XML version of the content page +<../dvng/step02/content.xml>`_ in Firefox 3.0 or Safari and see how the +XSLT will transform the result. (Use View Source to see the unthemed +content page.) + Python For First Stage ------------------------------ @@ -188,4 +196,31 @@ This has plenty of docstrings and comments, but let's walk through the lines: -#. **Line 4-6**. Setup some XML namespace-oriented constants. +#. **Lines 4-6**. Setup some XML namespace-oriented constants. + +#. **Lines 8-45**. Make a class that produces a reusable theme + processor. + +#. **Line 16-17**. Load the companion XSLT ``compiler.xsl``. This + operates on the theme to produce the ``dvfinalstage.xsl`` "compiled + themeset." + +#. **Lines 20-21**. Grab the theme and the rules file. + +#. **Lines 25-32**. For each rule, find the theme node that it points + at and add some "hints" to the theme node. These hints help the + ``compiler.xsl`` iterate over all the nodes in the theme, find the + places that have rules, and go find the right handler to generate a + rule. + +#. **Lines 35-36**. Run the compiler on the hinted theme to produce the + final XSLT document, then turn it into a processor. This is the + final stage. The processor can then be used over and over against + outgoing content pages. + +#. **Lines 38-45**. Read a content page into an etree and run the + processor against it. Return a string for the HTML of the themed + content page. + +Running this Python module from the ``step02`` directory produces the +same result as running ``xsltproc`` in Step 01. Modified: z3/deliverance/sandboxes/paul/docs/_sources/step03.txt ============================================================================== --- z3/deliverance/sandboxes/paul/docs/_sources/step03.txt (original) +++ z3/deliverance/sandboxes/paul/docs/_sources/step03.txt Tue May 20 02:40:43 2008 @@ -22,6 +22,12 @@ To do this, we'll gradually build up the support working backwards from the "compiled themeset". +.. note:: + + This step re-thinks the decisions made in Step 02. I left Step 02 + as it was, though, to show the thought process. + + Sample Data and Desired Output ---------------------------------------- @@ -266,10 +272,56 @@ :language: python :linenos: +We'll let the docstrings and comments provide the explanation. At a high +level, though: + +- Copy all the HTML for each theme directly into the rule file. The + compiler will then operate on this "compiled" rule file. + +- Add hints to the themes as before, but also, add id attributes to each + rule. This makes the ``compiler.xsl`` simpler when doing "joining" a + theme node to the rule that matched it. + Here is the new compiler file: .. literalinclude:: step03/compiler.xsl :language: xslt :linenos: +Again, we'll let the XML comments provide most of the documentation. The +changes require some high-level explanation: + +- Inside the variable, iterate over the theme nodes. + +- For those, copy over everything that isn't flagged as part of a rule. + +- For things that are part of a rule, pass control to a rule handler + (e.g. Line 70) + +Running the module against one of the sample content pages is easy:: + + $ python ./xform.py content2.html + + + + Second Theme Page Title + + + + +

Navigation

+

A Deeper Look At DVNG

+
Theme content to replace.
+
+ +Note that, since the module runs the debug method, we get ``xxx-cr.xml`` +and ``xxx-dvfinalstage.xsl`` output files. We can use these for +introspection to confirm that we're getting what we expect. Tools like +oXygen can then help run the transforms step by step, validate the +stages, and even set breakpoints in a debugger. + +Finally, you can load `an XML version of the content page +<../dvng/step03/content2.xml>`_ with the table-based theme, letting Firefox 3 or +Safari perform the XSLT transform on the client. Again, use View Source +to see the unthemed content page. \ No newline at end of file Modified: z3/deliverance/sandboxes/paul/docs/index.html ============================================================================== --- z3/deliverance/sandboxes/paul/docs/index.html (original) +++ z3/deliverance/sandboxes/paul/docs/index.html Tue May 20 02:40:43 2008 @@ -36,17 +36,18 @@

DVNG - Rewriting the XSLT Renderer?

-

Deliverance is a simple system for applying a common look-and-feel to all -pages across site, no matter what system generated the pages. Currently, -Deliverance has two modes it uses to render:

+

Deliverance is a simple system for applying a common look-and-feel to +all pages across a site, no matter what system generated the pages. +Currently, Deliverance has two modes it uses to render:

  • The Python Renderer uses lxml to manipulate HTML node trees during a request. This is the default renderer and the most supported.
  • -
  • The XSLT Renderer generates an XSLT stylesheet that is applied to the -content, transforming the content page into a themed result. For this -renderer, XSLT is nothing but an internal, intermediate language: -Deliverance integrators need never see a single line of XSLT.
  • +
  • The XSLT Renderer generates an XSLT stylesheet that is applied to +the content, transforming the content page into a themed result. For +this renderer, XSLT is nothing but an internal, intermediate +language: Deliverance integrators need never see a single line of +XSLT.

DVNG is an experiment in rewriting the XSLT Renderer to achieve some new @@ -58,25 +59,30 @@ XSLT stylesheet. The stages break the work into smaller, more easily debugged chunks, using a combination of Pythonic lxml programming and XSLT transformation to produce the final stage.

-

This final stage can be run with any XSLT processor and is no longer tied -to the original theme, rules, or Deliverance processing logic. Stated -differently, the final stage could be checked into Subversion and used -without even installing Deliverance on a production server.

+

This final stage can be run with any XSLT processor and is no longer +tied to the original theme, rules, or Deliverance processing logic. +Stated differently, the final stage could be checked into Subversion and +used without even installing Deliverance on a production server.

The goals include:

  • Speed. The current Deliverance renderers do a lot of work on each request. DVNG plans to do a lot of work once, with the result being usable not just between requests, but for as long as the theme and rules do not change.
  • -
  • Reliability. Much less complex.
  • -
  • Debuggability.
  • -
  • Extensibility.
  • +
  • Reliability. The production renderer is much less complex.
  • +
  • Debuggability. By making each stage of the rendering introspectable +in a “view source” fashion, you get some of the benefits of a +pipeline. Namely, you know what part of the process broke down.
  • +
  • Extensibility. Custom Deliverance rules, and even full-scale +extensions via imported XSLT, provide ways to make specialized changes +to the themes, rules, or even incoming content. All without adding +more features to Deliverance.

About This Document?

-

This walkthrough is aimed first at the Deliverance mailing list, where we -are considering design of the new specification and implementations.

+

This walkthrough is aimed first at the Deliverance mailing list, where +we are considering design of the new specification and implementations.

As such, we’ll gradually build the result, step by step, to show the thinking that went into this approach. In some ways, this is an advocacy document, meant not just to explain, but also to persuade. Apologies in Modified: z3/deliverance/sandboxes/paul/docs/searchindex.json ============================================================================== --- z3/deliverance/sandboxes/paul/docs/searchindex.json (original) +++ z3/deliverance/sandboxes/paul/docs/searchindex.json Tue May 20 02:40:43 2008 @@ -1 +1 @@ -[["index","step02","step03","step01"],["DVNG - Rewriting the XSLT Renderer","Step 02 - A “Compiler” for DVNG","Step 03 - Multi-theme support","Step 01 - The Minimum"],{"all":[0,1,2],"code":[],"consider":[2],"messi":[2],"prefix":[1,2],"dirnam":[2],"go":[1],"follow":[3,2],"disk":[1,2],"children":[1],"millisecond":[2],"intermedi":[0,2],"send":[3],"articl":[2],"to":[0,1,2,3],"program":[0],"ti":[0],"td":[2],"nodeset":[3],"spec":[2],"introduc":[3,2],"sourc":[3,2],"string":[2],"getrul":[1,2],"far":[2],"getpar":[2],"theme2":[2],"veri":[3,2],"retriev":[2],"look":[0,1,2,3],"wa":[1],"did":[3],"list":[0],"iter":[1],"try":[3,1],"p":[3,1,2],"tostr":[2],"small":[1],"div":[3,1,2],"setup":[1],"dv_namespac":[1,2],"themeswitch":[2],"the":[0,1,2,3],"smaller":[0],"xsltproc":[0,1,2,3],"multithem":[2],"second":[2],"design":[0],"pass":[3,1,2],"further":[3],"append":[1,2],"even":[0],"trick":[3,1]