On the Plone Foundation board, we have biweekly meetings for which the Foundation Secretary takes minutes. We approve them at the following meeting, and they are then published and emailed to the Foundation membership.
To make it easier for the secretary to take those minutes, live, during the meeting, including all the usual formatting for headings, bullet points, and the common parts of our minutes, Chrissy Wainwright created a TinyMCE template for Plone.org.
It consists of:
Plone.templates
that lists the available TinyMCE templates in JSON formatPlone.custom_plugins
telling TinyMCE to load its template pluginSee the ploneorg.core commit in full.
Over 11 years ago, during my first year working as a systems analyst / DBA at the University of Wisconsin Oshkosh, it was fate that I volunteered to have a look at a grant project that had come in from our College of Education and Human Services.
The $300,000 grant project was to create a sophisticated web portal for the Wisconsin Department of Public Instruction's new WIDA project, a multi-state consortium developing K-12 diagnostic tests for English Limited Learners.
The web site content would be partly public, partly private (login required), and would allow the viewing and downloading of documents and files., some of which were password-protected.
The content creators were educators, not technology specialists, so the entire user interface needed to be geared to non-technical users, with WYSIWYG editors and easy uploading of files and images, and had to allow content to be reviewed before being made public (workflow!).
Over the next three years, we formed a small design, programming, and support team that quickly delivered a beautiful, functionally rich web portal that was used by thousands of educators from over 20 states. All this was possible thanks to the flexibility and power of the open source Plone enterprise web content management system (http://plone.com).
My colleague, Brian Ledwell, and I began to demo Plone and what it could do for a number of units on campus, and we soon had many deployed Plone sites in use, for academic departments and colleges. What began as a grassroots effort to professionalize the university's web presence eventually won official adoption of Plone for the entire campus.
As of February 2015, UW Oshkosh has close to 300 production web sites built with Plone, including intranets, public sites (for academic and administrative units), and workflow (e-business) systems, supported by a small but dedicated team.
Over the years, that team has included students majoring in Computer Science, Information Systems, and Theatre, who have gone on to successful careers in Information Technology, sometimes in positions at UW Oshkosh.
Some have become leaders in the Plone open source community, participating in the User Interface and Security teams; contributing to PloneEdu, and hosting the Plone Symposium Midwest for 2013 and 2014. We have contributed several add-ons to the Plone universe: uwosh.timeslot, uwosh.northstar, uwosh.pfg.d2c, uwosh.snippets, uwosh.transitionbuttons.
Beginning March 1, 2015, I will be embarking on the next phase of my career, working freelance on Plone projects. While I am leaving behind my job at UW Oshkosh, my connection to valued colleagues and great friends continues, and so does the living legacy of the second largest Plone installation in the US*, and one of the largest in the world.
For this success, I thank my colleagues at UW Oshkosh, in particular my co-conspirator Brian Ledwell in bringing Plone to the campus, our former CIO Ken Splittgerber for having the confidence in us and our vision for the university, the many, many welcoming, brilliant, and kind members of the worldwide Plone community, but most especially the WebLion team at Penn State for showing us the way.
* The largest US Plone installation is University of Louisville's, initially built by Kurt Bendl and currently maintained and enhanced by Brandon Gaddie.
]]>The official Plone documentation at http://docs.plone.org/manage/deploying/front-end/nginx.html explains how to use Nginx with Plone.
The following is being integrated with the official documentation, but here it is for now.
The simplest way to protect confidential data a bit better is to serve your web site using only HTTPS.
To use HTTPS encryption you must first set up your server with SSL. This requires that you:
openssl
)View detailed Nginx SSL support instructions.
Here is a sample Nginx configuration that secures all web site traffic, by forcing all HTTP (port 80) traffic to be redirected to HTTPS (port 443).
It uses two server
blocks; the first listens for HTTP traffic and sends it to the second, which handles HTTPS traffic.
Some assumptions below:
yoursite.com.crt
and yoursite.com.key
in the /etc/ssl/localcerts/
directoryyoursite.com
Plone
# This adds security headers
add_header X-Frame-Options "SAMEORIGIN";
add_header Strict-Transport-Security "max-age=15768000; includeSubDomains";
add_header X-XSS-Protection "1; mode=block";
add_header X-Content-Type-Options "nosniff";
#add_header Content-Security-Policy "default-src 'self'; img-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'";
add_header Content-Security-Policy-Report-Only "default-src 'self'; img-src *; style-src 'self' 'unsafe-inline'; script-src 'self' 'unsafe-inline' 'unsafe-eval'";
# This specifies which IP and port Plone is running on.
# The default is 127.0.0.1:8080
upstream plone {
server 127.0.0.1:8080;
}
# this forces all unencrypted HTTP traffic on port 80 to be redirected to encrypted HTTPS
server {
listen 80;
server_name yoursite.com;
location / {
rewrite ^ https://$server_name$request_uri permanent;
}
}
server {
listen 443 default ssl;
ssl_certificate /etc/ssl/localcerts/yoursite.com.crt;
ssl_certificate_key /etc/ssl/localcerts/yoursite.com.key;
server_name yoursite.com;
access_log /var/log/nginx/yoursite.com.access.log;
error_log /var/log/nginx/yoursite.com.error.log;
# Note that domain name spelling in VirtualHostBase URL matters
# -> this is what Plone sees as the "real" HTTP request URL.
# "Plone" in the URL is your site ID (case sensitive)
location / {
rewrite ^/(.*)$ /VirtualHostBase/$scheme/yoursite.com:443/Plone/VirtualHostRoot/$1 break;
# this puts the originating request IP address in the logs
proxy_pass http://127.0.0.1:8080/;
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
}
Some time ago I threw together a script that lets you import many users into a Plone site. See http://www.uwosh.edu/ploneprojects/docs/how-tos/mass-or-batch-user-create.
Recently I found out that Plone's new plone.protect CSRF protection makes it harder to run a Script (Python) through the ZMI. When you click the Test tab, even though everything looks like it ran, in the event log you'll find an INFO message saying that the transaction was aborted because it may have been a CSRF exploit.
You can still run a Script (Python) from the ZMI by getting the value of the authentication ticket that plone.protect is expecting.
You will find the value of the authentication ticket has been appended to every clickable link within a Plone site that has plone.protect, e.g.
https://mysite.com/front-page/edit?_authenticator=b825811a8eb6beb048b45103f4e10256f0b06b56
Append it to the URL of the Test tab, so instead of going to the URL
https://mysite.com/importusers/ZScriptHTML_tryForm
you would go to
https://mysite.com/importusers/ZScriptHTML_tryForm?_authenticator=b825811a8eb6beb048b45103f4e10256f0b06b56
I modified the script so now you can run it from the command line on the server:
bin/client1 run importusers.py]]>
If you are running robot tests and you get the error
[ ERROR ] Error in file '/Users/kim/PloneBuilds/OshkoshScholars/test_oshkoshscholars.robot': Non-existing setting ''.
and
Test case name cannot be empty.
you should check the indentation of your robot test script. In my case, I had an extra space in each column from having copied & pasted this sample robot test script:
*** Settings *** Resource plone/app/robotframework/selenium.robot Test Setup Open test browser Test Teardown Close all browsers *** Test Cases *** Plone is installed Go to ${PLONE_URL} Page should contain Powered by Plone
whereas after correctly de-indenting it I no longer got the error (it's an annoyingly near-invisible problem!).
*** Settings *** Resource plone/app/robotframework/selenium.robot Test Setup Open test browser Test Teardown Close all browsers *** Test Cases *** Plone is installed Go to ${PLONE_URL} Page should contain Powered by Plone]]>
The venerable Products.Quills blogging add-on for Plone has been neglected for some time. I'd last used it on some 4.x sites but the eggs on the PyPi package Index were missing some files.
Quills has been tested with Plone 4.3.11. It has not been tested with Plone 5.
Now Products.Quills 1.8.1 and the matching quills.app 1.8.1 have been released to pypi:
Both add-ons have been updated with current Plone version PyPi classifiers
To install them in your Plone site, add this to your buildout.cfg
:
eggs =
Plone
Pillow
Products.Quills
then run bin/buildout
If you want to ensure you get the latest version of Products.Quills:
eggs =
Plone
Pillow
Products.Quills==1.8.1
I always pin egg versions, either there in the eggs
lines or later in a [versions]
section or in a separate versions.cfg
file, e.g.
[versions]
...
Products.Quills=1.8.1
I used the lovely zest.releaser tool to do that. Among other things, it tags the release in the GitHub repo, so that later on we can all find the exact state of the source code used to release that particular egg, e.g.
Recently I ran into difficulties (still unresolved) with another project that did NOT tag its releases in GitHub, and I've been unable to branch off the correct past state of its code to try to fix some bugs.
]]>I've been running Plone on Linode VMs (linode.com) for years now and have been very happy with them and the service.
At UW Oshkosh we run RedHat EL (the stable enterprise version) and we used to run SuSE EL before that. Above all, we prize reliability and stability over having the latest and greatest system packages that the young punks (er, kids) are using (I'm talking about *you*, Ubuntu!).
So when I started running Plone on my Linode VMs I started to use SuSE as well, and then when it became clear that SuSE was slowly dying, I switched to CentOS 5.5 (the RedHat EL clone) for the stability and longevity I knew it would have.
Because I have been running Plone sites on this particular Linode for years now, I hadn't had the opportunity to set up a new Linode VM with a shiny new kernel (or new distribution - still looking at you, Ubuntu).
The wonderful folks at Linode.com had been offering a *free upgrade* to VMs using their SSDs (solid state disks), which are so much faster than the old spindle drives. However, to take advantage of that free SSD upgrade, I first would have to switch to a 64-bit kernel.
I resisted this for months, not wanting to mess with Something That Works.
Eventually, I followed the documented procedure for switching to a 64-bit kernel and it went perfectly smoothly. Once that was done, I was able to take advantage of the SSD upgrade, and after a reboot my Linode VM and all its Plone sites were up and running flawlessly.
Today I made the mistake of making a small change to my Plone buildout, to upgrade one add-on package. (I won't say which package, in order to protect the innocent).
To my surprise, buildout pulled down a number of eggs that I wasn't expecting. After all, this was a small version upgrade to just one add-on, so why did it seem like the bad old days when Plone people didn't pin versions and spent hours tearing out their thinning hair in despair (hey, that rhymes!)?
I let buildout run, despite a growing sense of dread. When I restarted my clients, everything seemed to run just fine, except for errors in the log like
XSLTApplyError: xsltValueOf: text copy failed
...and as it turned out, none of the Diazo themes were being rendered - those sites looked pretty bare. I had to fix this (or restore from backup) in a hurry.
Googling around revealed that the problem was related to incorrect versions of lxml2, yet this particular Plone installation had been running for years without a hitch.
After looking over my *.cfg files carefully, I was sure I hadn't changed them except for this one version bump. It was when I happened to look through my buildout-cache/eggs folder (I used the Plone unified installer) and noticed that I had two eggs for lxml2: the usual one, and the x64 version.
The problem was that the new 64-bit kernel was causing buildout to build and install 64-bit versions of Python packages....into a Plone that had been built with 32-bit packages and binaries. Oops!
I decided that the easiest way to fix my problem was to re-run the Plone unified installer in a new target directory (in this case /opt/Plone-4.3.2-x64) so it would build and include a fully 64-bit Python.
The Sentry.io real-time error tracking service gives you detailed insight into production errors, so that you can often fix them BEFORE your clients even notice a problem and BEFORE their users get upset.
Sentry provides a free plan that is more than enough to handle a large number of Plone sites (limited to 1 team member and 5,000 events per day).
Sentry notifies you of errors in a variety of ways (email, by default) and it provides you with a dashboard of all your reported errors, which you can mark as resolved, you can ignore them (for a set amount of time), you can link them to an issue tracker such as GitHub, you can share the detailed error message (scrubbed of private data).
If you are like me, once you start using Sentry, you will:
Other things Sentry does: you can easily customize Plone's default error message page to pop up a nice looking dialog box in which a user can provide their name, email address, and description of what they were trying to do when they encountered an error. Not only is this good for YOU (because it helps you understand what led to the error), it is also FANTASTIC FOR YOUR CLIENT because their users now know that administrators have noticed their problem and are trying to fix it. This is a level of user satisfaction that goes above and beyond what most people have come to accept, which is to suffer in silence.
How it works: you sign up with Sentry, you declare any number of "projects", each of which gets a unique ID that you use in your buildout.cfg configuration.
In buildout.cfg, you want to add custom error logging configuration so that when an error is logged, it not only gets logged normally to your event.log or instance.log but it also gets sent to Sentry with the unique ID you were assigned.
(There are even finer grained ways of tracking multiple "releases" of each project, but that probably is useful only if you're deploying versions of, say, Facebook.com, which, presumably YOU are not if you are reading my lowly blog!)
Whether you installed Plone with the Unified Installer or some other buildout-based method, you will have to modify both buildout.cfg and base.cfg to use Sentry.
In a ZEO Plone 4.3 deployment, which I installed with the Unified Installer, buildout.cfg defines two ZEO clients, [client1] and [client2]. To do that cleanly, buildout.cfg extends base.cfg, which in turn contains a [client_base] section, which both [client1] and [client2] derive from.
We modify [client_base] by adding these lines:
[client_base]
...
event-log-custom =
%import raven.contrib.zope
<logfile>
path ${buildout:var-dir}/${:_buildout_section_name_}/event.log
level INFO
</logfile>
<sentry>
dsn https://YOURUNIQUEID@sentry.io/MOREUNIQUEID
level ERROR
</sentry>
Your specific "dns" line containing YOURUNIQUEID and MOREUNIQUEID will have come from your Sentry project definition.
You want your "path" value to match that of the "event-log" value defined in [client_base]. I haven't tried this, but you may be able to use a line like path ${event-log}
instead of path ${buildout:var-dir}/${:_buildout_section_name_}/event.log
In contrast, a Plone 4.2 ZEO deployment (also using the Unified Installer) is slightly different: both [client1] and [client2] are defined in base.cfg, so you have to append your custom configuration to both, and the value for "path" is different:
[client1]
...
event-log-custom =
%import raven.contrib.zope
<logfile>
path ${buildout:directory}/var/client1/event.log
level INFO
</logfile>
<sentry>
dsn https://YOURUNIQUEID@sentry.io/MOREUNIQUEID
level ERROR
</sentry>
and
[client2]
...
event-log-custom =
%import raven.contrib.zope
<logfile>
path ${buildout:directory}/var/client2/event.log
level INFO
</logfile>
<sentry>
dsn https://YOURUNIQUEID@sentry.io/MOREUNIQUEID
level ERROR
</sentry>
In both cases, the key point here is to ensure your Sentry "path" value matches what was defined for each client. As in the previous section, I haven't tried this, but you may be able to use a line like path ${event-log}
instead of path ${buildout:directory}/var/client1/event.log
and path ${buildout:directory}/var/client2/event.log
I haven't tested this myself but the idea is the same. You need to customize logging for the [instance], and that will depend on your buildout.cfg and base.cfg.
You also have to add "raven" to your buildout.cfg eggs:
eggs =
Plone
Pillow
...
raven
Now run buildout. Once you restart your ZEO clients, when they log an error they will continue appending to the log file defined in the "path" above but will also send the error to Sentry. Depending on how you set up Sentry, you will receive email notifications and you can view a dashboard of your errors.
In all likelihood, you will begin to be able to fix errors (software, user, or other) BEFORE anyone reports them to you, if they even bother to report the errors at all.
Your clients and their users may not even realize how much better a service you are providing them, but you will know, and you will have greatly increased your ability to retain satisfied customers, and that is golden.
]]>
Recently I wanted to include a URL in a PloneFormGen (PFG) form field's help text, and I wanted that URL to be clickable.
Normally, that isn't possible because help text (as with Plone description fields generally) are not rich text (HTML); they are plain text.
The key to doing this is to write or find some JavaScript that searches a text string for a URL expression and replaces that expression with the normal <a href="SOMEURL">SOMETEXT</a> tag.
Here is some JavaScript code that does this (it may not cover all cases, but it's not bad). Sorry, I don't recall where I found this on the web! Thank you to author(s) unknown...
// linkify the YouTube URL in the description of this field function linkify(inputText) { var replacedText, replacePattern1, replacePattern2, replacePattern3; //URLs starting with http://, https://, or ftp:// replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim; replacedText = inputText.replace(replacePattern1, '<a href="$1" target="_blank">$1</a>'); //URLs starting with "www." (without // before it, or it'd re-link the ones done above). replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim; replacedText = replacedText.replace(replacePattern2, '$1<a href="http://$2" target="_blank">$2</a>'); //Change email addresses to mailto:: links. replacePattern3 = /(([a-zA-Z0-9\-\_\.])+@[a-zA-Z\_]+?(\.[a-zA-Z]{2,6})+)/gim; replacedText = replacedText.replace(replacePattern3, '<a href="mailto:$1">$1</a>'); return replacedText; }
You'll want to invoke that JavaScript on your PFG form so it looks for and converts any plain text URLs into clickable ones.
It's easiest to save this JavaScript where you'll most easily be able to invoke it from your PFG form: inside the form! (Another place you could save the JavaScript on the site is the portal_skins/custom folder).
To save this JavaScript inside the PFG form, you must view the PFG form folder using the Zope Management Interface (ZMI): if your PFG form folder URL is
http://mysite.com/submissions
you'll want to go to:
http://mysite.com/submissions/manage_main
Then add a new File object using the drop down list at the top right of the page: select File and press the Add button.
In the ID field enter:
my_form_javascript
then press the Add button.
In the body of the new File object, you want to paste the above JavaScript function, but wrapped with a bit more to tell Plone that this is JavaScript:
<script type="text/javascript">
You also want the JavaScript to be loaded and run once the page (PFG form folder in this case) has finished loading (ie. it is ready), so you include this:
$(document).ready(function(){
All together this is what you paste into the body of the File object:
<script type="text/javascript"> $(document).ready(function(){ // linkify the YouTube URL in the description of this field function linkify(inputText) { var replacedText, replacePattern1, replacePattern2, replacePattern3; //URLs starting with http://, https://, or ftp:// replacePattern1 = /(\b(https?|ftp):\/\/[-A-Z0-9+&@#\/%?=~_|!:,.;]*[-A-Z0-9+&@#\/%=~_|])/gim; replacedText = inputText.replace(replacePattern1, '<a href="$1" target="_blank">$1</a>'); //URLs starting with "www." (without // before it, or it'd re-link the ones done above). replacePattern2 = /(^|[^\/])(www\.[\S]+(\b|$))/gim; replacedText = replacedText.replace(replacePattern2, '$1<a href="http://$2" target="_blank">$2</a>'); //Change email addresses to mailto:: links. replacePattern3 = /(([a-zA-Z0-9\-\_\.])+@[a-zA-Z\_]+?(\.[a-zA-Z]{2,6})+)/gim; replacedText = replacedText.replace(replacePattern3, '<a href="mailto:$1">$1</a>'); return replacedText; } $('.formHelp').each(function(index) { $(this).html(linkify($(this).text())); }); }); </script>
You'll also note that we threw in
$('.formHelp').each(function(index) { $(this).html(linkify($(this).text())); });
which invokes the linkify() function on every PFG form field's help text. (You don't have to invoke it on every field help text; you could invoke it on only specific fields' help text if you specified the CSS ID of a particular field's help text, but this is easier).
Now that you've saved the JavaScript, you must invoke it from your PFG form. PFG lets you inject JavaScript (and CSS) into any form very easily. You edit the PFG form folder and go to the Overrides tab and in the Header Injection field you enter an expression like
here/my_form_javascript
The press the Save button.
Now when you view the PFG form, any URLs in the PFG form's help text will be clickable (including "mailto:" links).
]]>
I have been curious how the "Contact" site action at the bottom of every Plone site was made to display the contact form in a popup window.
This line is how it's done:
<property name="modal" type="text">{}</property>
To make the "Accessibility" info display in a popup window, you
]]>
According to http://stackoverflow.com/questions/19548011/cannot-install-lxml-on-mac-os-x-10-9 the fix is to update your Xcode command line tools:
xcode-select --install
and then re-run buildout. It worked for me. :)
]]>For Plone 4.3 I implemented an External Method that obtains a special one-time access URL from Taylor & Francis' web site.
You can see this in action at the International Medieval Sermon Studies web site!
The External Method is secured with the ZMI's Security tab but it is also behind a couple of Plone pages, one of which requires logging in to read.
The Python script itself is:
from Products.CMFCore.utils import getToolByName
def mss_online(self):
# check if we are logged in
pm = getToolByName(self, 'portal_membership', None)
if not pm:
return "Unable to check if you are logged in. Please notify a site administrator."
user = pm.getAuthenticatedMember()
if str(user) == "Anonymous User":
return "You are not logged in."
BIG_URL = "http://www.tandfonline.com/tps/requestticket?ru=http://www.tandfonline.com/biglongurlwithparameters"
import urllib2
url = urllib2.urlopen(BIG_URL).read()
return "<META HTTP-EQUIV=\"Refresh\" CONTENT=\"0; URL=%s\"><html><head></head><body>You are being redirected to <a href=\"$redirURL\">tandfonline.com</a></body></html>" % url
I named the script mss_online.py
and placed it in the Plone installation directory’s “Extensions” subdirectory (e.g. /opt/Plone/zeocluster/Extensions/mss_online.py
).
Then, using the Zope Management Interface, e.g. mysite.net/manage_main, I added an External Method, and set:
To protect it from non-logged in access, I then used the Security tab to uncheck “Acquire permission settings” and check “Authenticated” for the View permission.
]]>If you've created a Diazo theme but don't (yet) have the time to make it work nicely with Plone's logged in user interface (e.g. for editing and managing content), you can use this somewhat dirty trick: disable the Diazo theme for anyone logged into your site.
This works if your site doesn't require users to log in to view content such as Intranet-like, password-protected areas of the site. The assumption is that the only people logging into your site will be content creators, editors, and site administrators.
To disable a Diazo theme for logged in users, add this rule to your rules.xml:
<notheme css:if-not-content="body.userrole-anonymous"/>
If, however, your site requires that users log in to view password-protected content, you probably want those users to still see lovely theme you've created, and you want users with Manager role to see the unthemed Plone UI.
If you want logged in users to still see the themed site but you want Managers to see the unthemed site, use this rule:
<notheme css:if-content="body.userrole-manager"/>]]>
Sentry.io includes a feature that pops up a nice looking dialog box to ask the user for more information (their name, email address, and what they were doing or trying to do) when an error occurs in your software. (Read more in the Sentry blog post or in the Sentry user documentation.)
For Plone, this is most easily used by customizing the default_error_message.pt
page template.
First, you have to sign up with Sentry (you may be able to use just the free service), and create a project if you haven't already done so (as I described in my previous blog post).
Then, in your Sentry dashboard, click on the User Feedback button to take you to a page that shows the JavaScript code you need. That code contains your unique Sentry project ID.
Because anything exposed on the public internet can be abused, you need to specify which domain(s) Sentry should accept this dialog box connection from.
You do this by going to your Sentry project settings page, scrolling down to "Allowed Domains", and provide (one per line) the domain(s) that should show the user feedback dialog box.
Note: the following has been tested with Plone 4.2.
In your Plone site, go to the Management Interface, e.g. mysite.com/manage_main, then portal_skins, plone_templates, default_error_message.
Click the Customize button. (Note: you may have already customized this template, in which case go to portal_skins/custom to find your already-customized default_error_message).
If you look at the structure of the default_error_message page template, you'll see there are two major <metal>
tags: one to handle "not found" errors (<metal:notfound tal:condition="python:err_type=='NotFound'">
), the other to handle everything else (<metal:othererror tal:condition="python: err_type!='NotFound'"
).
At the end of each of these two tags you will insert your JavaScript code. It should looks like this for the "not found" <metal>
tag:
<!-- Sentry JS SDK 2.1.+ required -->
<script src="https://cdn.ravenjs.com/2.1.0/raven.min.js"></script>
<script>
// configure the SDK as you normally would
Raven.config('https://YOURUNIQUEID@sentry.io/MOREUNIQUEID').install();
function handleRouteError(err) {
Raven.captureException(err);
Raven.showReportDialog();
};
err = new Error('404')
handleRouteError(err);
</script>
and to handle any other type of error, at the end of the "everything else" <metal>
tag:
<!-- Sentry JS SDK 2.1.+ required -->
<script src="https://cdn.ravenjs.com/2.1.0/raven.min.js"></script>
<script>
// configure the SDK as you normally would
Raven.config('https://YOURUNIQUEID@sentry.io/MOREUNIQUEID').install();
function handleRouteError(err) {
Raven.captureException(err);
Raven.showReportDialog();
};
err = new Error('other error')
handleRouteError(err);
</script>
Now when a person encounters that Plone error page, either because of a missing content item or some other problem, they will be presented with a dialog box like this:
Even if they don't fill it out or, say, it was a search engine crawler that caused the error, Sentry will still receive the error and you will be notified and will see it in the dashboard.
Any information provided by the user in the dialog box will also appear, giving you sometimes just that extra tidbit of information you need to figure out what caused the problem.
]]>
If you have this in your /etc/fail2ban/jail.local
configuration file:
# "bantime" is the number of seconds that a host is banned.
bantime = 31536000 # 1 year
# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
findtime = 604800 # 7 days
and you get these errors when you restart fail2ban (service fail2ban restart
):
WARNING Wrong value for 'findtime' in 'ssh'. Using default one: '600'
WARNING Wrong value for 'bantime' in 'ssh'. Using default one: '600'
change it to this (put the comment on a separate line):
# "bantime" is the number of seconds that a host is banned.
# 1 year
bantime = 31536000
# A host is banned if it has generated "maxretry" during the last "findtime"
# seconds.
# 7 days
findtime = 604800
This is explained in the following bug report:
fail2ban: Incorrect parsing of commented text after reading a value from config file
If you want to set a permanent ban time, use a negative number.
# "bantime" is the number of seconds that a host is banned.]]>
# permanent ban
bantime = -1