src/pyams_skin/metas.py
changeset 144 3198f3bcf67d
parent 142 5e603a22d753
child 367 a211d8c17334
equal deleted inserted replaced
143:60f49532b262 144:3198f3bcf67d
       
     1 #
       
     2 # Copyright (c) 2008-2015 Thierry Florac <tflorac AT ulthar.net>
       
     3 # All Rights Reserved.
       
     4 #
       
     5 # This software is subject to the provisions of the Zope Public License,
       
     6 # Version 2.1 (ZPL).  A copy of the ZPL should accompany this distribution.
       
     7 # THIS SOFTWARE IS PROVIDED "AS IS" AND ANY AND ALL EXPRESS OR IMPLIED
       
     8 # WARRANTIES ARE DISCLAIMED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
       
     9 # WARRANTIES OF TITLE, MERCHANTABILITY, AGAINST INFRINGEMENT, AND FITNESS
       
    10 # FOR A PARTICULAR PURPOSE.
       
    11 #
       
    12 
       
    13 __docformat__ = 'restructuredtext'
       
    14 
       
    15 
       
    16 # import standard library
       
    17 
       
    18 # import interfaces
       
    19 from pyams_skin.interfaces.extension import IGoogleAnalyticsInfo
       
    20 from pyams_skin.interfaces.metas import IHTMLContentMetas, IMetaHeader
       
    21 from pyams_utils.interfaces.tales import ITALESExtension
       
    22 from pyramid.interfaces import IRequest
       
    23 
       
    24 # import packages
       
    25 from pyams_utils.adapter import adapter_config, ContextRequestViewAdapter
       
    26 from zope.interface import implementer, Interface
       
    27 
       
    28 
       
    29 #
       
    30 # 'metas' TALES extension
       
    31 #
       
    32 
       
    33 @adapter_config(name='metas', context=(Interface, IRequest, Interface), provides=ITALESExtension)
       
    34 class MetasTalesExtension(ContextRequestViewAdapter):
       
    35     """extension:metas TALES extension"""
       
    36 
       
    37     def render(self, context=None):
       
    38         if context is None:
       
    39             context = self.context
       
    40         result = []
       
    41         for name, adapter in sorted(self.request.registry.getAdapters((context, self.request, self.view),
       
    42                                                                       IHTMLContentMetas),
       
    43                                     key=lambda x: getattr(x[1], 'order', 9999)):
       
    44             result.extend([meta.render() for meta in adapter.get_metas()])
       
    45         return '\n\t'.join(result)
       
    46 
       
    47 
       
    48 #
       
    49 # Custom metas headers
       
    50 #
       
    51 
       
    52 @implementer(IMetaHeader)
       
    53 class HTTPEquivMeta(object):
       
    54     """HTTP-Equiv meta header"""
       
    55 
       
    56     def __init__(self, http_equiv, value):
       
    57         self.http_equiv = http_equiv
       
    58         self.value = value
       
    59 
       
    60     def render(self):
       
    61         return '''<meta http-equiv="{http_equiv}" content="{value}" />'''.format(http_equiv=self.http_equiv,
       
    62                                                                                  value=self.value)
       
    63 
       
    64 
       
    65 @implementer(IMetaHeader)
       
    66 class ValueMeta(object):
       
    67     """Basic value meta header"""
       
    68 
       
    69     def __init__(self, name, value):
       
    70         self.name = name
       
    71         self.value = value
       
    72 
       
    73     def render(self):
       
    74         return '''<meta {name}="{value}" />'''.format(name=self.name,
       
    75                                                       value=self.value)
       
    76 
       
    77 
       
    78 @implementer(IMetaHeader)
       
    79 class ContentMeta(object):
       
    80     """Content meta header"""
       
    81 
       
    82     def __init__(self, name, value):
       
    83         self.name = name
       
    84         self.value = value
       
    85 
       
    86     def render(self):
       
    87         return '''<meta name="{name}" content="{value}" />'''.format(name=self.name,
       
    88                                                                      value=self.value)
       
    89 
       
    90 
       
    91 @implementer(IMetaHeader)
       
    92 class PropertyMeta(object):
       
    93     """Property meta header"""
       
    94 
       
    95     def __init__(self, property, value):
       
    96         self.property = property
       
    97         self.value = value
       
    98 
       
    99     def render(self):
       
   100         return '''<meta property="{property}" content="{value}" />'''.format(property=self.property,
       
   101                                                                              value=self.value)
       
   102 
       
   103 
       
   104 @implementer(IMetaHeader)
       
   105 class LinkMeta(object):
       
   106     """Link meta header"""
       
   107 
       
   108     def __init__(self, rel, type, href):
       
   109         self.rel = rel
       
   110         self.type = type
       
   111         self.href = href
       
   112 
       
   113     def render(self):
       
   114         return '''<link rel="{rel}" type="{type}" href="{href}" />'''.format(rel=self.rel,
       
   115                                                                              type=self.type,
       
   116                                                                              href=self.href)
       
   117 
       
   118 
       
   119 #
       
   120 # Default metas headers
       
   121 #
       
   122 
       
   123 @adapter_config(name='layout', context=(Interface, Interface, Interface), provides=IHTMLContentMetas)
       
   124 class LayoutMetasAdapter(ContextRequestViewAdapter):
       
   125     """Basic layout metas adapter"""
       
   126 
       
   127     order = -1
       
   128 
       
   129     @staticmethod
       
   130     def get_metas():
       
   131         yield HTTPEquivMeta('X-UA-Compatible', 'IE=edge,chrome=1')
       
   132         yield ContentMeta('HandheldFriendly', 'True')
       
   133         yield ContentMeta('viewport', 'width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no')
       
   134 
       
   135 
       
   136 @adapter_config(name='content-type', context=(Interface, Interface, Interface), provides=IHTMLContentMetas)
       
   137 class ContentTypeMetasAdapter(ContextRequestViewAdapter):
       
   138     """Content-type metas adapter"""
       
   139 
       
   140     order = 10
       
   141 
       
   142     @staticmethod
       
   143     def get_metas():
       
   144         yield HTTPEquivMeta('Content-Type', 'text/html; charset=utf-8')
       
   145         yield ValueMeta('charset', 'utf-8')
       
   146 
       
   147 
       
   148 @adapter_config(name='analytics', context=(Interface, Interface, Interface), provides=IHTMLContentMetas)
       
   149 class VerificationCodeMetasAdapter(ContextRequestViewAdapter):
       
   150     """Google verification code metas adapter"""
       
   151 
       
   152     order = 20
       
   153 
       
   154     def __new__(cls, context, request, view):
       
   155         info = IGoogleAnalyticsInfo(request.root)
       
   156         if not info.verification_code:
       
   157             return None
       
   158         return ContextRequestViewAdapter.__new__(cls)
       
   159 
       
   160     def get_metas(self):
       
   161         info = IGoogleAnalyticsInfo(self.request.root)
       
   162         yield ContentMeta('google-site-verification', info.verification_code)