--- a/src/pyams_skin/metas.py Tue Jan 29 10:48:24 2019 +0100
+++ b/src/pyams_skin/metas.py Tue Jan 29 15:55:17 2019 +0100
@@ -21,9 +21,11 @@
from pyams_skin.interfaces.configuration import IConfiguration
from pyams_skin.interfaces.extension import IGoogleAnalyticsInfo
from pyams_skin.interfaces.metas import IHTMLContentMetas, IMetaHeader
+from pyams_skin.layer import IPyAMSUserLayer
from pyams_utils.adapter import ContextRequestViewAdapter, adapter_config
from pyams_utils.interfaces.site import ISiteRoot
from pyams_utils.interfaces.tales import ITALESExtension
+from pyams_utils.url import canonical_url
#
@@ -54,102 +56,69 @@
@implementer(IMetaHeader)
-class HTMLTagMeta(object):
+class BaseMeta(object):
+ """Base HTML meta header"""
+
+ def __init__(self, tag='meta', value=None, **attrs):
+ self.tag = tag
+ self.value = value
+ self.attrs = attrs
+
+ def render(self):
+ attributes = ' '.join(('{}="{}"'.format(k, v) for k, v in self.attrs.items()))
+ if self.value:
+ return '<{0} {1}>{2}</{0}>'.format(self.tag, attributes, self.value)
+ else:
+ return '<{} {} />'.format(self.tag, attributes)
+
+
+class HTMLTagMeta(BaseMeta):
"""HTML tag meta header"""
def __init__(self, tag, content, **attrs):
- self.tag = tag
- self.content = escape_value(content)
- self.attrs = attrs
-
- def render(self):
- return '''<{tag} {attrs}>{content}</{tag}>'''.format(tag=self.tag,
- attrs=' '.join(('{0}="{1}"'.format(*value) for value in
- self.attrs.items())),
- content=self.content)
+ super(HTMLTagMeta, self).__init__(tag, content, **attrs)
-@implementer(IMetaHeader)
-class HTTPEquivMeta(object):
+class HTTPEquivMeta(BaseMeta):
"""HTTP-Equiv meta header"""
def __init__(self, http_equiv, value):
- self.http_equiv = http_equiv
- self.value = escape_value(value)
-
- def render(self):
- return '''<meta http-equiv="{http_equiv}" content="{value}" />'''.format(http_equiv=self.http_equiv,
- value=self.value)
+ super(HTTPEquivMeta, self).__init__(**{'http-equiv': http_equiv, 'content': escape_value(value)})
-@implementer(IMetaHeader)
-class ValueMeta(object):
+class ValueMeta(BaseMeta):
"""Basic value meta header"""
def __init__(self, name, value):
- self.name = name
- self.value = escape_value(value)
-
- def render(self):
- return '''<meta {name}="{value}" />'''.format(name=self.name,
- value=self.value)
+ super(ValueMeta, self).__init__(**{name: escape_value(value)})
-@implementer(IMetaHeader)
-class ContentMeta(object):
+class ContentMeta(BaseMeta):
"""Content meta header"""
def __init__(self, name, value):
- self.name = name
- self.value = escape_value(value)
-
- def render(self):
- return '''<meta name="{name}" content="{value}" />'''.format(name=self.name,
- value=self.value)
+ super(ContentMeta, self).__init__(name=name, content=escape_value(value))
-@implementer(IMetaHeader)
-class PropertyMeta(object):
+class PropertyMeta(BaseMeta):
"""Property meta header"""
def __init__(self, property, value):
- self.property = property
- self.value = escape_value(value)
-
- def render(self):
- return '''<meta property="{property}" content="{value}" />'''.format(property=self.property,
- value=self.value)
+ super(PropertyMeta, self).__init__(property=property, content=escape_value(value))
-@implementer(IMetaHeader)
-class SchemaMeta(object):
+class SchemaMeta(BaseMeta):
"""Schema.org property meta header"""
def __init__(self, name, value):
- self.name = name
- self.value = escape_value(value)
-
- def render(self):
- return '''<meta itemprop="{name}" content="{value}" />'''.format(name=self.name,
- value=self.value)
+ super(SchemaMeta, self).__init__(itemprop=name, content=escape_value(value))
-@implementer(IMetaHeader)
-class LinkMeta(object):
+class LinkMeta(BaseMeta):
"""Link meta header"""
- def __init__(self, rel, type, href, title=None):
- self.rel = rel
- self.type = type
- self.href = escape_value(href)
- self.title = title
-
- def render(self):
- title = ' title="{}"'.format(self.title) if self.title else ''
- return '''<link rel="{rel}" type="{type}" href="{href}" {title} />'''.format(rel=self.rel,
- type=self.type,
- href=self.href,
- title=title)
+ def __init__(self, rel, type, href, **kwargs):
+ super(LinkMeta, self).__init__('link', rel=rel, type=type, href=escape_value(href), **kwargs)
#
@@ -192,6 +161,17 @@
yield ContentMeta('description', config.description)
+@adapter_config(name='canonical', context=(Interface, IPyAMSUserLayer, Interface), provides=IHTMLContentMetas)
+class CanonicalURLMetasAdapter(ContextRequestViewAdapter):
+ """Canonical URL metas adapter"""
+
+ order = 2
+
+ def get_metas(self):
+ target_url = canonical_url(self.context, self.request).replace('+', '%2B')
+ yield BaseMeta(rel='canonical', href=target_url)
+
+
@adapter_config(name='content-type', context=(Interface, Interface, Interface), provides=IHTMLContentMetas)
class ContentTypeMetasAdapter(ContextRequestViewAdapter):
"""Content-type metas adapter"""
@@ -204,11 +184,11 @@
yield ValueMeta('charset', 'utf-8')
-@adapter_config(name='analytics', context=(Interface, Interface, Interface), provides=IHTMLContentMetas)
+@adapter_config(name='google-site-verification', context=(Interface, Interface, Interface), provides=IHTMLContentMetas)
class VerificationCodeMetasAdapter(ContextRequestViewAdapter):
"""Google verification code metas adapter"""
- order = 20
+ order = 11
def __new__(cls, context, request, view):
info = IGoogleAnalyticsInfo(request.root)