# HG changeset patch # User Thierry Florac # Date 1494926848 -7200 # Node ID 7dd11f00b114353c7f892cf08ee959975620670f # Parent 137705383aaf51fd34ad3d339ead1bc7ba44f400 Added function, class and TALES extension for Fanstatic resources management diff -r 137705383aaf -r 7dd11f00b114 src/pyams_utils/fanstatic.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/pyams_utils/fanstatic.py Tue May 16 11:27:28 2017 +0200 @@ -0,0 +1,72 @@ +# +# Copyright (c) 2008-2015 Thierry Florac +# All Rights Reserved. +# +# This software is subject to the provisions of the Zope Public License, +# Version 2.1 (ZPL). A copy of the ZPL should accompany this distribution. +# THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED +# WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED +# WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS +# FOR A PARTICULAR PURPOSE. +# +from pyramid.path import DottedNameResolver + +__docformat__ = 'restructuredtext' + + +# import standard library + +# import interfaces +from pyams_utils.interfaces.tales import ITALESExtension + +# import packages +from fanstatic import Resource +from fanstatic.core import set_resource_file_existence_checking, render_css, NeededResources +from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter +from zope.interface import Interface + + +def render_js(url, defer=False): + return '' % (url, 'defer' if defer else '') + + +class ExternalResource(Resource): + """Fanstatic external resource""" + + def __init__(self, library, path, defer=False, **kwargs): + set_resource_file_existence_checking(False) + try: + if 'renderer' in kwargs: + del kwargs['renderer'] + if 'bottom' not in kwargs: + kwargs['bottom'] = path.endswith('.js') + Resource.__init__(self, library, path, renderer=self.render, **kwargs) + finally: + set_resource_file_existence_checking(True) + self.defer = defer + + def render(self, library_url): + if self.relpath.endswith('.css'): + return render_css(self.relpath) + elif self.relpath.endswith('.js'): + return render_js(self.relpath, self.defer) + else: + return '' + + +def get_resource_path(resource, signature='--static--', versioning=True): + """Get path for given resource""" + res = NeededResources(publisher_signature=signature, versioning=versioning) + return '{0}/{1}'.format(res.library_url(resource.library), resource.relpath) + + +@adapter_config(name='resource_path', context=(Interface, Interface, Interface), provides=ITALESExtension) +class FanstaticTalesExtension(ContextRequestViewAdapter): + """extension:fanstatic() TALES extension""" + + def render(self, resource): + library, resource_name = resource.split(':') + resolver = DottedNameResolver() + module = resolver.maybe_resolve(library) + resource = getattr(module, resource_name) + return get_resource_path(resource)