#
# Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
# 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.
#
"""PyAMS_utils.fanstatic module
This module is a helper module to handle Fanstatic resources.
It includes several TALES extensions which can be used to include resources from a Chameleon
template, or to get path of a given resources from a template.
"""
from fanstatic import Resource
from fanstatic.core import NeededResources, render_css, set_resource_file_existence_checking
from pyramid.path import DottedNameResolver
from zope.interface import Interface
from pyams_utils.adapter import ContextRequestViewAdapter, adapter_config
from pyams_utils.interfaces.tales import ITALESExtension
__docformat__ = 'restructuredtext'
[docs]def render_js(url, defer=False):
"""Render tag to include Javascript resource"""
return '<script type="text/javascript" src="%s" %s></script>' % (url, 'defer' if defer else '')
[docs]class ExternalResource(Resource):
"""Fanstatic external resource"""
dependency_nr = 0
def __init__(self, library, path, defer=False, resource_type=None, **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
if resource_type:
self.resource_type = resource_type
else:
self.resource_type = path.rsplit('.', 1)[1].lower()
[docs] def render(self, library_url):
"""Render resource tag"""
if self.resource_type == 'css':
return render_css(self.relpath)
if self.resource_type == 'js':
return render_js(self.relpath, self.defer)
return ''
[docs]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)
[docs]@adapter_config(name='resource_path', context=(Interface, Interface, Interface),
provides=ITALESExtension)
class FanstaticTalesExtension(ContextRequestViewAdapter):
"""tales:resource_path() TALES extension
This TALES extension generates an URL matching a given Fanstatic resource.
Resource is given as a string made of package name (in dotted form) followed by a colon and
by the resource name.
For example::
.. code-block:: html
<div tal:attributes="data-ams-plugin-pyams_content-src
extension:resource_path('pyams_content.zmi:pyams_content')" />
"""
[docs] @staticmethod
def render(resource):
"""TALES extension rendering method"""
library, resource_name = resource.split(':')
resolver = DottedNameResolver()
module = resolver.maybe_resolve(library)
resource = getattr(module, resource_name)
return get_resource_path(resource)
[docs]@adapter_config(name='need_resource', context=(Interface, Interface, Interface),
provides=ITALESExtension)
class FanstaticNeededResourceTalesExtension(ContextRequestViewAdapter):
"""tales:need_resource() TALES extension
This extension generates a call to Fanstatic resource.need() function to include given resource
into generated HTML code.
Resource is given as a string made of package name (in dotted form) followed by a colon and by
the resource name.
For example::
.. code-block:: html
<tal:var define="tales:need_resource('pyams_content.zmi:pyams_content')" />
"""
[docs] @staticmethod
def render(resource):
"""TALES extension rendering method"""
library, resource_name = resource.split(':')
resolver = DottedNameResolver()
module = resolver.maybe_resolve(library)
resource = getattr(module, resource_name)
resource.need()
return ''