Pelican provides support for generating content from two markup languages - reStructuredText (the default) and Markdown (if installed). For the most part both markup languages generate similar output, except when using Pygments to generate code blocks with syntax highlighting.
Code blocks generated from reStructuredText will use the CSS class
to handle the syntax highlighting, while Markdown will use the
class by default. This can cause problems when developing themes for Pelican
users who may be using either reStructuredText or Markdown, or users who choose
to generate content using both markup languages.
Fortunately you can customise how the Markdown processor generates its output
MD_EXTENSIONS setting in the
pelicanconf.py file. You can
configure the Markdown processor to generate code blocks using the
CSS class by inserting the following entry in you
MD_EXTENSIONS = ['codehilite(css_class=highlight)']
More information about pelicanconf.py settings can be found in the Pelican documentation.
On a number of occasions I have needed to make a site available via both HTTP
and HTTPS which can result in creating two almost identical
VirtualHost stanzas. The HTTPS stanza usually ends up being a
copy & paste of the HTTP stanza with the SSL certificate stuff tacked on to the
end. This means you generally end up with a file that is something like the
# file: /etc/apache2/sites-available/site.example.com.conf <VirtualHost *:80> ServerName site.example.com ServerAdmin firstname.lastname@example.org DocumentRoot /var/www/site ErrorLog /var/log/apache2/site-error_log CustomLog /var/log/apache2/site-access_log vhost_combined # ... some rewrite rules, ACLs, etc ... </VirtualHost> <VirtualHost *:443> ServerName site.example.com ServerAdmin email@example.com DocumentRoot /var/www/site ErrorLog /var/log/apache2/site-error_log CustomLog /var/log/apache2/site-access_log vhost_combined # ... duplicate rewrite rules, ACLs, etc ... SSLEngine On SSLCertificateFile ssl/crt/wc.example.com.crt SSLCertificateKeyFile ssl/key/wc.example.com.key </VirtualHost>
This method tends to break the "don't repeat yourself" (DRY) principle and can
lead to inconsistencies if you make a typo, or forget to make changes to both
stanzas. One method I have found to overcome this is to make use of the
The first step is to take all of the configuration settings that are common to both the HTTP and HTTPS stanzas and place them in a new file:
# file: /etc/apache2/sites-include/site.example.com.conf ServerName site.example.com ServerAdmin firstname.lastname@example.org DocumentRoot /var/www/site ErrorLog /var/log/apache2/site-error_log CustomLog /var/log/apache2/site-access_log vhost_combined # ... some rewrite rules, ACLs, etc ...
Note: I generally use Debian systems which have the convention of storing
VirtualHost configuration files in
/etc/apache2/sites-available, so I like
to keep these common setting files in
You can then
Include this common setting file in both of your
# file: /etc/apache2/sites-available/site.example.com.conf <VirtualHost *:80> Include sites-include/site.example.com.conf </VirtualHost> <VirtualHost *:443> Include sites-include/site.example.com.conf SSLEngine On SSLCertificateFile ssl/crt/wc.example.com.crt SSLCertificateKeyFile ssl/key/wc.example.com.key </VirtualHost>
Using this method you only need to make changes in one location
sites-include/site.example.com.conf) and they will be applied to both HTTP
You can also do something similar if you use the same wildcard SSL certificate
in a number of different
VirtualHost files. First move the common SSL
settings into a new file:
# file: /etc/apache2/ssl/site.example.com.conf SSLEngine On SSLCertificateFile ssl/crt/wc.example.com.crt SSLCertificateKeyFile ssl/key/wc.example.com.key
Include the SSL settings file in your HTTPS
# file: /etc/apache2/sites-available/site.example.com.conf <VirtualHost *:80> Include sites-include/site.example.com.conf </VirtualHost> <VirtualHost *:443> Include sites-include/site.example.com.conf Include ssl/wc.example.com.conf </VirtualHost>
This can be particularly useful if you have a number of extra SSL settings that need to be configured.
Following on from my last post, I have now split the
out into its own Python package to make it easier to reuse in other projects. I
have called it wsgi-liveserver and it is the first Python package that I have
released. The package can be downloaded from PyPI. The code can be found on
GitHub and a welcome any feedback.
Selenium is a really nice framework for testing web application front-ends by automating actions through a web browser, but it also requires a web server to be running so that the browser can interact with the web application. Most other tests usually interact with the code directly, so this requirement can also lead to a slight problem... how should the web server be started when running tests?
The simplest way to run a Selenium test is to manually start up a web server for your application and then run the tests against it, but this can get a bit tedious after a while (especially if you keep forgetting to start the server).
Django provides a
LiveServerTestCase which automates starting up a web
server to serve up your Django application, run your Selenium tests, and then
stop the server again. This is a really nice approach, but I wanted to be able
to do something similar when I am not using Django.
Last week I came across the flask-testing framework which provides similar
functionality for Flask applications. The flask-testing
LiveServerTestCase is inspired by the Django version, but is much
simpler. Unfortunately it is also a bit specific to Flask applications.
What I really wanted was a something that could be used for any WSGI compliant
web application. So I wrote my own which is loosely based on the
flask-testing version. You simply inherit from the
class instead of from
unittest.TestCase when creating your test class,
create_app() method to return your WSGI application and,
write your tests as normal. When you run your tests it will handle starting and
stopping the web server in the background as required. I have written a very
basic example Bottle application called bottle-selenium to show it in
I originally wrote this to use with Bottle applications, mainly because they are very simple to work with. My eventual goal is to use this for testing the development of Roundup instances, so it should work with any WSGI compliant web application.
unittest module provides support for testing that an exception is
raised using the
assertRaises() method, but sometime we need to also test
that the exception message is what is expected. Python v2.7 introduced the
assertRaisesRegexp() method which can be used to test exception messages
using regular expressions, but if you are stuck with v2.6 or earlier you will
need to do something like:
import unittest def raise_exception(yup=True): if yup: raise ValueError('Yup, exception raised.') class BasicExceptionTest(unittest.TestCase): def test_message(self): try: raise_exception(True) self.fail() except ValueError as e: self.assertEqual(str(e), 'Yup, exception raised.') if __name__ == '__main__': unittest.main(verbosity=2)
test_message() we first wrap the function we are testing
raise_exception()) in a
except statement to
catch any exception that may be raised. If no exception is raised then we call
fail() to signal that the test has failed. If the correct exception has
been raised (in this case
ValueError) we use
test that the exception message is correct. If an exception that we were not
expecting is raised, then it will be handled by the
TestCase class and
the test will be marked as having an error. With this simple test pattern every
possible outcome should be handled correctly.
If you plan to be writing a lot of these sorts of tests, then it may be worth
creating your own
TestCase class that provides an assert method for
testing exception messages:
import unittest def raise_exception(yup=True): if yup: raise ValueError('Yup, exception raised.') class ExceptionMessageTestCase(unittest.TestCase): def assertRaisesMessage(self, exception, msg, func, *args, **kwargs): try: func(*args, **kwargs) self.fail() except exception as e: self.assertEqual(str(e), msg) class MessageExceptionTest(ExceptionMessageTestCase): def test_message(self): self.assertRaisesMessage(ValueError, 'Yup, exception raised.', raise_exception, True) if __name__ == '__main__': unittest.main(verbosity=2)
assertRaisesMessage() method is very similar to the
assertRaises() method except that it also takes a
msg argument that
will be used to compare against the exception message.
Both of these test patterns could also be extended to include the ability to
use regular expression to test messages (similar to
but I generally find that simple string comparisons are usually enough for my