Skip to content

Commit

Permalink
Merge 9b79f4f into 40cfc4c
Browse files Browse the repository at this point in the history
  • Loading branch information
hvelarde committed Sep 1, 2017
2 parents 40cfc4c + 9b79f4f commit f4d478d
Show file tree
Hide file tree
Showing 6 changed files with 75 additions and 113 deletions.
9 changes: 9 additions & 0 deletions CHANGES.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,15 @@ There's a frood who really knows where his towel is.
2.10.2 (unreleased)
^^^^^^^^^^^^^^^^^^^

- Update Tweet Button code; code clean up and refactor.
[hvelarde]

- Twitter widgets now respect users' privacy.
[hvelarde]

- Remove redundant metadata as Twitter can use Open Graph properties as fall back (closes `#112 <https://github.com/collective/sc.social.like/issues/112>`_).
[hvelarde]

- Remove useless scale caching on the request as it seems to be causing colateral issues (closes `#109 <https://github.com/collective/sc.social.like/issues/109>`_).
[rodfersou]

Expand Down
84 changes: 32 additions & 52 deletions sc/social/like/plugins/twitter/browser.py
Original file line number Diff line number Diff line change
@@ -1,83 +1,63 @@
# -*- coding:utf-8 -*-
"""Helper view to generate the Tweet Button widget.
More information:
* https://dev.twitter.com/web/tweet-button
* https://dev.twitter.com/web/overview/privacy
"""
from Acquisition import aq_inner
from plone import api
from plone.api.exc import InvalidParameterError
from Products.CMFPlone.utils import safe_unicode
from Products.Five import BrowserView
from Products.Five.browser.pagetemplatefile import ViewPageTemplateFile
from Products.PythonScripts.standard import url_quote
from sc.social.like.behaviors import ISocialMedia
from sc.social.like.config import IS_PLONE_5
from sc.social.like.interfaces import ISocialLikeSettings
from sc.social.like.utils import get_content_image
from sc.social.like.utils import get_language
from urllib import urlencode
from zope.component import getMultiAdapter


class PluginView(BrowserView):

twitter_enabled = False
language = 'en'
"""Helper view to generate the Tweet Button widget."""

metadata = ViewPageTemplateFile('templates/metadata.pt')
plugin = ViewPageTemplateFile('templates/plugin.pt')
link = ViewPageTemplateFile('templates/link.pt')

def __init__(self, context, request):
self.context = context
self.title = context.title
self.description = context.Description()
self.context = aq_inner(context)
self.request = request
# FIXME: the following could rise unexpected exceptions
# move it to a new setup() method
# see: http://docs.plone.org/develop/plone/views/browserviews.html#creating-a-view
self.portal_state = getMultiAdapter((self.context, self.request),
name=u'plone_portal_state')
self.portal = self.portal_state.portal()
self.site_url = self.portal_state.portal_url()
self.portal_title = self.portal_state.portal_title()
self.url = context.absolute_url()
self.language = get_language(context)
self.image = get_content_image(context)
self.urlnoscript = (
u'http://twitter.com/home?status=' +
url_quote(u'{0} - {1} via {2}'.format(
safe_unicode(self.context.title),
self.context.absolute_url(),
self.via)
)
)

@property
def is_plone_5(self):
return IS_PLONE_5

@property
def typebutton(self):
record = ISocialLikeSettings.__identifier__ + '.typebutton'
try:
return api.portal.get_registry_record(record)
except InvalidParameterError:
return ''
def portal_url(self):
portal = api.portal.get()
return portal.absolute_url()

def canonical_url(self):
"""Return canonical URL if available; otherwise, context URL."""
if ISocialMedia.providedBy(self.context):
return self.context.canonical_url
else:
return self.context.absolute_url()

@property
def via(self):
record = ISocialLikeSettings.__identifier__ + '.twitter_username'
try:
return api.portal.get_registry_record(record)
except InvalidParameterError:
return ''
return api.portal.get_registry_record(record, default='')

def share_link(self):
params = dict(
text=safe_unicode(self.context.Title()).encode('utf-8'),
url=self.context.absolute_url(),
)
if self.via:
params['via'] = self.via
params = {
'text': self.context.Title(),
'url': self.context.absolute_url(),
}

via = self.via()
if via:
params['via'] = via

url = 'https://twitter.com/intent/tweet?' + urlencode(params)
return url

def image_url(self):
"""Return image URL."""
return self.image.url if self.image else None
def dnt(self):
record = ISocialLikeSettings.__identifier__ + '.do_not_track'
return api.portal.get_registry_record(record, default=False)
27 changes: 13 additions & 14 deletions sc/social/like/plugins/twitter/templates/link.pt
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
<tal:twitter i18n:domain="sc.social.like">
<!-- Twitter -->
<a href="https://twitter.com/intent/tweet"
class="slPrivacy"
title="Tweet it! (open in new window)"
tal:attributes="href view/share_link"
onclick="javascript:window.open(this.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"
i18n:attributes="title">
<img src="share-linkedin.png"
alt="Tweet it!"
i18n:attributes="alt"
tal:attributes="src string:${view/site_url}/++resource++sl_images/share-twitter.png" />
</a>
</tal:twitter>
<!-- Twitter -->
<a class="slPrivacy"
href="https://twitter.com/intent/tweet"
title="Tweet (opens in new window)"
tal:attributes="href view/share_link"
onclick="javascript:window.open(this.href, '', 'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=600,width=600');return false;"
i18n:domain="sc.social.like"
i18n:attributes="title">
<img src="share-twitter.png"
alt="Tweet"
i18n:attributes="alt"
tal:attributes="src string:${view/portal_url}/++resource++sl_images/share-twitter.png" />
</a>
4 changes: 1 addition & 3 deletions sc/social/like/plugins/twitter/templates/metadata.pt
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
</tal:comment>
<tal:twitter condition="not:view/is_plone_5">
<meta name="twitter:card" content="summary_large_image" />
<meta name="twitter:image" tal:condition="view/image_url" tal:attributes="content view/image_url" />
<meta name="twitter:site" tal:attributes="content string:@${view/via}" />
<meta name="twitter:title" tal:attributes="content view/title" />
<meta name="twitter:description" tal:attributes="content view/description" />
<meta tal:condition="view/dnt" name="twitter:dnt" content="on">
</tal:twitter>
21 changes: 7 additions & 14 deletions sc/social/like/plugins/twitter/templates/plugin.pt
Original file line number Diff line number Diff line change
@@ -1,14 +1,7 @@
<tal:twitter>
<!-- Twitter -->
<a href="https://twitter.com/share"
class="twitter-share-button"
tal:attributes="data-count view/typebutton;
data-via view/via;
data-url view/url;
data-lang view/language;
data-text here/Title;">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0],p=/^http:/.test(d.location)?'http':'https';if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src=p+'://platform.twitter.com/widgets.js';fjs.parentNode.insertBefore(js,fjs);}}(document, 'script', 'twitter-wjs');</script>
<noscript>
<a tal:attributes="href view/urlnoscript">Tweet</a>
</noscript>
</tal:twitter>
<!-- Twitter -->
<a class="twitter-share-button"
href="https://twitter.com/intent/tweet"
tal:attributes="data-text here/Title;
data-url view/canonical_url;
data-via view/via">Tweet</a>
<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>
43 changes: 13 additions & 30 deletions sc/social/like/tests/test_plugin_twitter.py
Original file line number Diff line number Diff line change
Expand Up @@ -73,21 +73,24 @@ def setUp(self):
def test_plugin_view_metadata(self):

def get_meta_content(name):
"""Return the content attribute of the meta tag specified by name."""
return html.find('*/meta[@name="{0}"]'.format(name)).attrib['content']

"""Return the content attribute of the meta tag specified."""
meta = html.find('*/meta[@name="{0}"]'.format(name))
if meta is not None:
return meta.attrib['content']
view = self.newsitem.restrictedTraverse(self.plugin.view())
record = ISocialLikeSettings.__identifier__ + '.twitter_username'
api.portal.set_registry_record(record, 'plone')

from lxml import etree
html = etree.HTML(view.metadata())
self.assertEqual(get_meta_content('twitter:card'), 'summary_large_image')
expected = r'http://nohost/plone/lorem-ipsum/@@images/[0-9a-f--]+.png'
self.assertRegexpMatches(get_meta_content('twitter:image'), expected)
self.assertEqual(get_meta_content('twitter:site'), '@plone')
self.assertEqual(get_meta_content('twitter:title'), 'Lorem Ipsum')
self.assertEqual(get_meta_content('twitter:description'), 'Neque Porro')

# privacy settings
self.assertIsNone(get_meta_content('twitter:dnt'))
self.settings.do_not_track = True
html = etree.HTML(view.metadata())
self.assertEqual(get_meta_content('twitter:dnt'), 'on')

def test_plugin_view_html(self):
view = self.newsitem.restrictedTraverse(self.plugin.view())
Expand All @@ -99,33 +102,13 @@ def test_privacy_plugin_view_html(self):

view = self.portal.restrictedTraverse(self.plugin.view())
html = view.link()
self.assertIn('Tweet it!', html)
self.assertIn('Tweet', html)

def test_plugin_twitter_username(self):
self.settings.twitter_username = '@simplesconsult'

view = self.newsitem.restrictedTraverse(self.plugin.view())
html = view.plugin()
self.assertIn('data-via="@simplesconsult"', html)

def test_plugin_urlnoscript_encoding(self):
self.newsitem.setTitle(u'Notícia')
self.settings.twitter_username = '@simplesconsult'

view = self.newsitem.restrictedTraverse(self.plugin.view())
html = view.plugin()
self.assertIn('%20via%20%40simplesconsult">Tweet', html)

def test_plugin_language(self):
self.newsitem.setLanguage('pt-br')
view = self.newsitem.restrictedTraverse(self.plugin.view())
html = view.plugin()
self.assertIn('data-lang="pt-br"', html)

self.newsitem.setLanguage('en')
self.settings.twitter_username = 'simplesconsult'
view = self.newsitem.restrictedTraverse(self.plugin.view())
html = view.plugin()
self.assertIn('data-lang="en"', html)
self.assertIn('data-via="simplesconsult"', html)

def test_share_link(self):
view = self.newsitem.restrictedTraverse(self.plugin.view())
Expand Down

0 comments on commit f4d478d

Please sign in to comment.