source: products/quintagroup.seoptimizer/branches/refactoring2.3.0/quintagroup/seoptimizer/browser/views.py @ 1789

Last change on this file since 1789 was 1789, checked in by mylan, 14 years ago

#140: Remove needless SEOControlPanel view class from views module

  • Property svn:eol-style set to native
File size: 14.9 KB
Line 
1from sets import Set
2from DateTime import DateTime
3from Acquisition import aq_inner
4from zope.component import queryAdapter
5from plone.app.controlpanel.form import ControlPanelView
6
7from Products.Five.browser import BrowserView
8from Products.CMFCore.utils import getToolByName
9from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
10from Products.CMFPlone import PloneMessageFactory as pmf
11
12from quintagroup.seoptimizer import SeoptimizerMessageFactory as _
13from quintagroup.seoptimizer import interfaces
14
15SEPERATOR = '|'
16SEO_PREFIX = 'seo_'
17PROP_PREFIX = 'qSEO_'
18SUFFIX = '_override'
19PROP_CUSTOM_PREFIX = 'qSEO_custom_'
20
21class SEOContext( BrowserView ):
22    """ This class contains methods that allows to edit html header meta tags.
23    """
24
25    def isSEOTabVisibile(self):
26        context = aq_inner(self.context)
27        portal_properties = getToolByName(context, 'portal_properties')
28        seo_properties = getToolByName(portal_properties, 'seo_properties')
29        content_types_with_seoproperties = seo_properties.getProperty('content_types_with_seoproperties', '')
30        return bool(self.context.portal_type in content_types_with_seoproperties)
31
32    def getSEOProperty( self, property_name, accessor='' ):
33        """ Get value from seo property by property name.
34        """
35        context = aq_inner(self.context)
36
37        if context.hasProperty(property_name):
38            return context.getProperty(property_name)
39
40        if accessor:
41            method = getattr(context, accessor, None)
42            if not callable(method):
43                return None
44
45            # Catch AttributeErrors raised by some AT applications
46            try:
47                value = method()
48            except AttributeError:
49                value = None
50
51            return value
52
53    def seo_title( self ):
54        """ Generate SEO Title from SEO properties.
55        """
56        return self.getSEOProperty( 'qSEO_title', accessor='Title' )
57
58    def seo_robots( self ):
59        """ Generate SEO Robots from SEO properties.
60        """
61        robots = self.getSEOProperty( 'qSEO_robots' )
62        return robots and robots or 'ALL'
63
64    def seo_description( self ):
65        """ Generate Description from SEO properties.
66        """
67
68        return self.getSEOProperty( 'qSEO_description', accessor = 'Description')
69
70    def seo_distribution( self ):
71        """ Generate Distribution from SEO properties.
72        """
73        dist = self.getSEOProperty( 'qSEO_distribution' )
74
75        return dist and dist or 'Global'
76
77    def seo_customMetaTags( self ):
78        """        Returned seo custom metatags from default_custom_metatags property in seo_properties
79        (global seo custom metatags) with update from seo custom metatags properties in context (local seo custom metatags).
80        """
81        tags = self.seo_globalCustomMetaTags()
82        loc = self.seo_localCustomMetaTags()
83        names = [i['meta_name'] for i in tags]
84        add_tags = []
85        for i in loc:
86            if i['meta_name'] in names:
87                for t in tags:
88                    if t['meta_name'] == i['meta_name']:
89                        t['meta_content'] = i['meta_content']
90            else:
91                add_tags.append(i)
92        tags.extend(add_tags)
93        return tags
94
95    def seo_globalWithoutLocalCustomMetaTags( self ):
96        """        Returned seo custom metatags from default_custom_metatags property in seo_properties
97        (global seo custom metatags) without seo custom metatags from properties in context (local seo custom metatags).
98        """
99        glob = self.seo_globalCustomMetaTags()
100        loc = self.seo_localCustomMetaTags()
101        names = [i['meta_name'] for i in loc]
102        tags = []
103        for i in glob:
104            if i['meta_name'] not in names:
105                tags.append(i)
106        return tags
107
108    def seo_localCustomMetaTags( self ):
109        """ Returned seo custom metatags from properties in context (local seo custom metatags).
110        """
111        result = []
112        property_prefix = 'qSEO_custom_'
113        context = aq_inner(self.context)
114        for property, value in context.propertyItems():
115            if property.startswith(property_prefix) and property[len(property_prefix):]:
116                result.append({'meta_name'    : property[len(property_prefix):],
117                               'meta_content' : value})
118        return result
119
120    def seo_globalCustomMetaTags( self ):
121        """ Returned seo custom metatags from default_custom_metatags property in seo_properties.
122        """
123        result = []
124        context = aq_inner(self.context)
125        site_properties = getToolByName(context, 'portal_properties')
126        if hasattr(site_properties, 'seo_properties'):
127            custom_meta_tags = getattr(site_properties.seo_properties, 'default_custom_metatags', [])
128            for tag in custom_meta_tags:
129                name_value = tag.split(SEPERATOR)
130                if name_value[0]:
131                    result.append({'meta_name'    : name_value[0],
132                                   'meta_content' : len(name_value) == 2 and name_value[1] or ''})
133        return result
134
135    def seo_nonEmptylocalMetaTags( self ):
136        """
137        """
138        return bool(self.seo_localCustomMetaTags())
139
140    def seo_html_comment( self ):
141        """ Generate HTML Comments from SEO properties.
142        """
143        html_comment = self.getSEOProperty( 'qSEO_html_comment' )
144        return html_comment and html_comment or '' 
145
146    def meta_keywords( self ):
147        """ Generate Meta Keywords from SEO properties (global and local) with Subject,
148            depending on the options in configlet.
149        """
150        prop_name = 'qSEO_keywords'
151        accessor = 'Subject'
152        context = aq_inner(self.context)
153        keywords = Set([])
154        pprops = getToolByName(context, 'portal_properties')
155        sheet = getattr(pprops, 'seo_properties', None)
156        method = getattr(context, accessor, None)
157        if not callable(method):
158            return None
159
160        # Catch AttributeErrors raised by some AT applications
161        try:
162            subject = Set(method())
163        except AttributeError:
164            subject = keywords
165
166        if sheet:
167          settings_use_keywords_sg = sheet.getProperty('settings_use_keywords_sg')
168          settings_use_keywords_lg = sheet.getProperty('settings_use_keywords_lg')
169          global_keywords = Set(sheet.getProperty('additional_keywords', None))
170          local_keywords = Set(context.getProperty(prop_name, None))
171          # Subject overrides global seo keywords and global overrides local seo keywords
172          if [settings_use_keywords_sg, settings_use_keywords_lg] == [1, 1]:
173              keywords = subject
174          # Subject overrides global seo keywords and merge global and local seo keywords
175          elif [settings_use_keywords_sg, settings_use_keywords_lg] == [1, 2]:
176              keywords = subject | local_keywords
177          # Global seo keywords overrides Subject and global overrides local seo keywords
178          elif [settings_use_keywords_sg, settings_use_keywords_lg] == [2, 1]:
179              keywords = global_keywords
180          # Global seo keywords overrides Subject and merge global and local seo keywords
181          elif [settings_use_keywords_sg, settings_use_keywords_lg] == [2, 2]:
182              keywords = global_keywords | local_keywords
183          # Merge Subject and global seo keywords and global overrides local seo keywords
184          elif [settings_use_keywords_sg, settings_use_keywords_lg] == [3, 1]:
185              keywords = subject | global_keywords
186          # Merge Subject and global seo keywords and merge global and local seo keywords
187          elif [settings_use_keywords_sg, settings_use_keywords_lg] == [3, 2]:
188              keywords = subject | global_keywords | local_keywords
189          else:
190              keywords = subject
191        else:
192            keywords = subject
193
194        return tuple(keywords)
195
196    def seo_keywords( self ):
197        """ Generate SEO Keywords from SEO properties (global merde local).
198        """
199        prop_name = 'qSEO_keywords'
200        context = aq_inner(self.context)
201        keywords = Set([])
202        pprops = getToolByName(context, 'portal_properties')
203        sheet = getattr(pprops, 'seo_properties', None)
204
205        if sheet:
206            settings_use_keywords_sg = sheet.getProperty('settings_use_keywords_sg')
207            settings_use_keywords_lg = sheet.getProperty('settings_use_keywords_lg')
208            global_keywords = Set(sheet.getProperty('additional_keywords', None))
209            local_keywords = Set(context.getProperty(prop_name, None))
210            keywords = global_keywords | local_keywords
211        else:
212            keywords = ''
213        return tuple(keywords)
214
215    def seo_canonical( self ):
216        """ Generate canonical URL from SEO properties.
217        """
218        purl = getToolByName(self.context, 'portal_url')()
219        canpath = queryAdapter(self.context, interfaces.ISEOCanonicalPath)
220        return purl + canpath.canonical_path()
221
222
223class SEOContextPropertiesView( BrowserView ):
224    """ This class contains methods that allows to manage seo properties.
225    """
226    template = ViewPageTemplateFile('templates/seo_context_properties.pt')
227
228    def test( self, condition, first, second ):
229        """
230        """
231        return condition and first or second
232
233    def getMainDomain(self, url):
234        """ Get a main domain.
235        """
236        url = url.split('//')[-1]
237        dompath = url.split(':')[0]
238        dom = dompath.split('/')[0]
239        return '.'.join(dom.split('.')[-2:])
240
241    def validateSEOProperty(self, property, value):
242        """ Validate a seo property.
243        """
244        purl = getToolByName(self.context, 'portal_url')()
245        state = ''
246        if property == PROP_PREFIX+'canonical':
247            # validate seo canonical url property
248            pdomain = self.getMainDomain(purl)
249            if not pdomain == self.getMainDomain(value):
250                state = _('canonical_msg', default=u'Canonical URL mast be in ${pdomain} domain.', mapping={'pdomain': pdomain})
251        return state
252
253    def setProperty(self, property, value, type='string'):
254        """ Add a new property.
255
256        Sets a new property with the given id, value and type or changes it.
257        """
258        context = aq_inner(self.context)
259        state = self.validateSEOProperty(property, value)
260        if not state:
261            if context.hasProperty(property):
262                context.manage_changeProperties({property: value})
263            else:
264                context.manage_addProperty(property, value, type)
265        return state
266
267    def manageSEOProps(self, **kw):
268        """ Manage seo properties.
269        """
270        context = aq_inner(self.context)
271        state = ''
272        delete_list, seo_overrides_keys, seo_keys = [], [], []
273        seo_items = dict([(k[len(SEO_PREFIX):],v) for k,v in kw.items() if k.startswith(SEO_PREFIX)])
274        for key in seo_items.keys():
275            if key.endswith(SUFFIX):
276                seo_overrides_keys.append(key[:-len(SUFFIX)])
277            else:
278                seo_keys.append(key)
279        for seo_key in seo_keys:
280            if seo_key == 'custommetatags':
281                self.manageSEOCustomMetaTagsProperties(**kw)
282            else:
283                if seo_key in seo_overrides_keys and seo_items.get(seo_key+SUFFIX):
284                    seo_value = seo_items[seo_key]
285                    t_value = 'string'
286                    if type(seo_value)==type([]) or type(seo_value)==type(()): t_value = 'lines'
287                    state = self.setProperty(PROP_PREFIX+seo_key, seo_value, type=t_value)
288                    if state:
289                        return state
290                elif context.hasProperty(PROP_PREFIX+seo_key):
291                    delete_list.append(PROP_PREFIX+seo_key)
292        if delete_list:
293            context.manage_delProperties(delete_list)
294        return state
295
296    def setSEOCustomMetaTags(self, custommetatags):
297        """ Set seo custom metatags properties.
298        """
299        context = aq_inner(self.context)
300        for tag in custommetatags:
301            self.setProperty('%s%s' % (PROP_CUSTOM_PREFIX, tag['meta_name']), tag['meta_content'])
302
303    def delAllSEOCustomMetaTagsProperties(self):
304        """ Delete all seo custom metatags properties.
305        """
306        context = aq_inner(self.context)
307        delete_list = []
308        for property, value in context.propertyItems():
309            if property.startswith(PROP_CUSTOM_PREFIX)  and not property == PROP_CUSTOM_PREFIX:
310                delete_list.append(property)
311        if delete_list:
312            context.manage_delProperties(delete_list)
313
314    def updateSEOCustomMetaTagsProperties(self, custommetatags):
315        """ Update seo custom metatags properties.
316        """
317        context = aq_inner(self.context)
318        site_properties = getToolByName(context, 'portal_properties')
319        globalCustomMetaTags = []
320        if hasattr(site_properties, 'seo_properties'):
321            custom_meta_tags = getattr(site_properties.seo_properties, 'default_custom_metatags', [])
322            for tag in custom_meta_tags:
323                name_value = tag.split(SEPERATOR)
324                if name_value[0]:
325                    globalCustomMetaTags.append({'meta_name'    : name_value[0],
326                                                 'meta_content' : len(name_value) == 1 and '' or name_value[1]})
327        for tag in custommetatags:
328            meta_name, meta_content = tag['meta_name'], tag['meta_content']
329            if meta_name:
330                if not [gmt for gmt in globalCustomMetaTags if (gmt['meta_name']==meta_name and gmt['meta_content']==meta_content)]:
331                    self.setProperty('%s%s' % (PROP_CUSTOM_PREFIX, meta_name), meta_content)
332
333    def manageSEOCustomMetaTagsProperties(self, **kw):
334        """ Update seo custom metatags properties, if enabled checkbox override or delete properties.
335
336        Change object properties by passing either a mapping object
337        of name:value pairs {'foo':6} or passing name=value parameters.
338        """
339        context = aq_inner(self.context)
340        self.delAllSEOCustomMetaTagsProperties()
341        if kw.get('seo_custommetatags_override'):
342            custommetatags = kw.get('seo_custommetatags', {})
343            self.updateSEOCustomMetaTagsProperties(custommetatags)
344
345    def __call__( self ):
346        """ Perform the update seo properties and redirect if necessary, or render the page Call method.
347        """
348        context = aq_inner(self.context)
349        request = self.request
350        form = self.request.form
351        submitted = form.get('form.submitted', False)
352        if submitted:
353            state = self.manageSEOProps(**form)
354            if not state:
355                state = _('seoproperties_saved', default=u'Content SEO properties have been saved.')
356                context.plone_utils.addPortalMessage(state)
357                kwargs = {'modification_date' : DateTime()} 
358                context.plone_utils.contentEdit(context, **kwargs)
359                return request.response.redirect(self.context.absolute_url())
360            context.plone_utils.addPortalMessage(state, 'error')
361        return self.template()
Note: See TracBrowser for help on using the repository browser.