A simple jQuery component for hiding email addresses from spammers.
This document describes the zest.emailhider package.
This package depends on jquery.pyproxy to integrate python code with jquery code.
For every content item in your site you can have exactly one email address, as we look up the email address for an object by its UID. For objects for which you want this you should register a simple adapter to the IMailable interface, so we can ask this adapter for an email attribute and a UID method. The ‘emailhider’ view is provided to generate the placeholder link.
Special case: when the uid contains ‘email’ or ‘address’ it is clearly no real uid. In that case we do nothing with the IMailable interface but we try to get a property with this ‘uid’ from the property sheet of the portal. Main use case is of course the ‘email_from_address’, but you can add other addresses as well, like ‘info_email’. If you want to display the email_from address in for example a static portlet on any page in the site, use this html code:
Instructions for your own package
What do you need to do if you want to use this in your own package, for your own content type?
First you need to make your content type adaptable to the IMailable interface, either directly or via an adapter.
If your content type already has a UID method (like all Archetypes content types) and an email attribute, you can use some zcml like this:
<class class=".content.MyContentType"> <implements interface="zest.emailhider.interfaces.IMailable" /> </class>
If not, then you need to register an adapter for your content type that has this method and attribute. For example something like this:
from zope.component import adapts from zope.interface import implements from zest.emailhider.interfaces import IMailable from your.package.interfaces import IMyContentType class MailableAdapter(object): adapts(IMyContentType) implements(IMailable) def __init__(self, context): self.context = context def UID(self): return self.context.my_special_uid_attribute @property def email(self): return self.context.getSomeContactAddress()
Second, in the page template of your content type you need to add code to show the placeholder text instead of the real email address:
<span>For more information contact us via email:</span> <span tal:replace="structure context/@@emailhider" />
Note that if you want this to still work when zest.emailhider is not installed, you can use this code instead:
<span tal:replace="structure context/@@emailhider|context/email" />
This shows the unprotected plain text email when zest.emailhider is is not available. When you are using zest.emailhider 2.6 or higher this works a bit better, as we have introduced an own browser layer: the @@emailhider page is only available when zest.emailhider is actually installed in the Plone Site. This also makes it safe to use zest.emailhider when you have more than one Plone Site in a single Zope instance and want emailhider to only be used in one them.
Note that the generated code in the template is very small, so you can also look at the page template in zest.emailhider and copy some code from there and change it to your own needs. As long as your objects can be found by UID in the uid_catalog and your content type can be adapted to IMailable to get the email attribute, it should all work fine.
Note on KSS usage in older releases
For reference, this is the normal line in the Condition field of ++resource++kukit.js (all on one line):
python: not here.restrictedTraverse('@@plone_portal_state').anonymous() and here.restrictedTraverse('@@kss_devel_mode').isoff()
and this is the normal line in the Condition field of ++resource++kukit-devel.js (all on one line):
python: not here.restrictedTraverse('@@plone_portal_state').anonymous() and here.restrictedTraverse('@@kss_devel_mode').ison()
History of zest.emailhider package
- Moved to github. [maurits]
- Added MANIFEST.in so our generated .mo files are added to the source distribution. [maurits]
- Register our browser views only for our own new browser layer. Added an upgrade step for this. This makes it easier for other packages to have a conditional dependency on zest.emailhider. [maurits]
- Updated call to ‘jq_reveal_email’ to use the one at the root of the site to avoid security errors. [vincent]
- Updated jquery.pyproxy dependency to at least 0.3.1 and removed the now no longer needed clean_string call. [maurits]
- Not only look up a fake uid for email_from_address as portal property, but do this for any fake uid that has ‘email’ or ‘address’ in it. Log warnings when no email address can be found for a fake or real uid. [maurits]
- Added two upgrade steps to upgrade from 1.x by installing jquery.pyproxy and running our kss step (which just removes our no longer needed kss file). [maurits]
- Use jquery.pyproxy instead of KSS. This makes the page load much less for anonymous users. [vincent+maurits]
- Made reveal_email available always, as it should just work whenever we want to hide the glocal ‘email_from_address’. If we have a real uid target, then try to adapt that target to the IMailable interface and if that fails we just silently do nothing. [maurits]
- Using kss.plugin.cacheability and added it as a dependency. [jladage]
- Allow to set the uid to email_from_address. [jladage]
- Changed the KSS to use the load event instead of the click event - it now either works transparently, or asks the user to activate JS. [simon]
- Added translations and modified template to use them. [simon]
- Initial creation of project. [simon]
- Initial creation of project. [simon]