Jul 232017
 

For a while there XML.com didn’t handle tags on submitted news items very well. If a tag was included that was in a different case to an existing tag, the preview and publish would result in a 500 server error. Fortunately this was something that wasn’t visible to the outside world, but annoying nonetheless.

Wagtail allows case-insensitive tags, and I had already turned that on (it would be confusing to have searches for the tags “XSLT” and “xslt” return different results, for example). Articles and news items submitted using the standard interface behaved properly, it was just the news items submitted by people without logins on the system that didn’t.

It turns out that the problem lay in the way I called the get_or_create() method, which is used to look up the tags in the database and then create them if they don’t exist. In my code, that looked like this:

tag, create = Tag.objects.get_or_create(name=tag_name)

By default, this is a case-sensitive method (as it should be, for the general case). To make the lookup case-insensitive, you use name__iexact instead of name. The next problem I found was that no tags were being created if the tag didn’t already exist in the database. To create the tag, if you’re using name__iexact instead of name for the tag lookup, you also need to give the get_or_create() method a defaults parameter to use when creating the tag. Now that line looks like this:

tag, create = Tag.objects.get_or_create(defaults={'name': tag_name},
                                        name__iexact=tag_name)

and it all works the way it’s meant to.

Apr 082017
 

If you have MathML on your WordPress site, using the Mathjax system to show it, then you need to know that Mathjax is shutting down the CDN as of April 30, 2017. If, like me, you use the MathJax-LaTeX plugin, the solution is easy.

Go to the Plugins – Settings – MathJax-LaTeX page. Uncheck the “Use MathJax CDN Service?” checkbox, and add https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.0/MathJax.js to the “Custom MathJax location?” text field. You can, of course, also download the MathJax scripts and install locally, but I prefer to use a CDN.

Save the changes, and you’re all set! Unfortunately there isn’t an equivalent of the MathJax ‘latest’ for the scripts, so every now and then you’ll need to update the location, but other than that there should be no differences.

Mar 262017
 

Let’s Encrypt has made it much easier for web sites to use https instead of http, even those on shared hosting. In my case, all I needed to do was ask my ISP, Canadian Web Hosting, to move my accounts to a server that supports a cPanel extension (I assume this one). Installing the certs is trivial.

Changing the basic WordPress setting was easy – update the WordPress Address (URL) and Site Address (URL) settings in General. This did break a lot of image links, mostly because I’ve had my blog on WordPress for so long that I still had all my images in a custom image directory and the gallery couldn’t find them any more. That took a certain amount of fiddling, and I haven’t yet got all the images in the old posts back to the way they were.

Another thing that broke was my spam detection. I used Spam Karma for many years, and even after it was no longer updated it was suitable for my needs. But it doesn’t work with https for some reason. I’ve now switched to Antispam Bee and find it does what I need. I haven’t noticed any spam slipping through, nor real comments being marked as spam. Most of the competitors had some feature I didn’t like, such as by default deleting comments without my having a chance to check them. That would be useful on sites with lots of spam, but not necessary for mine. It has a well-deserved high rating on the WordPress plugin site.

Overall, switching my sites to https cost me a couple of hours work and the time waiting for the new server DNS to propagate. Well worth it.

Feb 012017
 

I coded XML.com in Wagtail, a CMS based on Django. It works well for my needs and I like Python as a programming language. One of the big reasons I like Wagtail is that it includes a powerful enough but not overly complicated workflow with roles and a built-in moderation and preview system.

But, I wanted a system where people could submit news items that would go into the moderation queue without needing to sign up for a login first. Fortunately, Wagtail makes that possible, and there’s a nice article by Erin Mullaney at Wagtail: 2 Steps for Adding Pages Outside of the CMS that details all the steps you need. It all worked nicely in more recent versions of Wagtail (thanks, Erin!) except for one part, the notification that the news item is in the moderation queue. That wasn’t a stop-ship item, so XML.com launched without those emails working.

I’ve now found the source of the problem. It turns out that when you submit a news item in this way, it doesn’t have a login identity attached to it (obviously, since there isn’t one). The send_notification function that sends the email uses templates, and these templates use the login identity of the author in the body of the email. Since that doesn’t exist, the whole function fails.

That means the solution is easy. The affected templates are wagtailadmin/notifications/submitted.txt and wagtailadmin/notifications/submitted.html, and Wagtail lets you customize the admin templates. I put my customized admin templates into a utils application, which contains all my utilities for the site. My utils/templates/wagtailadmin/notifications/submitted.txt file now has the content

{% extends 'wagtailadmin/notifications/submitted.txt' %}
{% load i18n %}

{% block content %}
{% blocktrans with page=revision.page|safe %}The page "{{ page }}" has been submitted for moderation.{% endblocktrans %}

{% trans "You can preview the page here:" %} {{ settings.BASE_URL }}{% url 'wagtailadmin_pages:preview_for_moderation' revision.id %}
{% trans "You can edit the page here:" %} {{ settings.BASE_URL }}{% url 'wagtailadmin_pages:edit' revision.page.id %}
{% endblock %}

Similar changes are necessary for the wagtailadmin/notifications/submitted.html file if you want to send HTML emails instead.

May 102016
 

If you read the documentation closely enough, of course all the information is there. Getting the order of operations right, however, can cause the odd issue.

Developing Django apps means applying migrations, and those don’t always do what’s expected. In that case, you can roll back to the n-1 migration by using ./manage.py migrate [app_label] {n-1_migration_label}, then delete the nth migration, then edit the models.py to try again.

To clean up the database from some third-party app you decide you don’t want after all, you use ./manage.py migrate [app_label] zero to get rid of the migrations from that app. You have to run this before deleting the app from your settings.py file.

Apr 242016
 

One of my client websites suddenly started giving an error: Error establishing a database connection. When I went to the /wp-admin URL, the error was still there.

This particular website is on shared hosting, so I logged into the CPanel and checked the database was still there. Then I checked the database and found some issues with some of the tables.

[site.wp_links] error: Table upgrade required. Please do "REPAIR TABLE `wp_links`" or dump/reload to fix it!
[site.wp_options] error: Table upgrade required. Please do "REPAIR TABLE `wp_options`" or dump/reload to fix it!
[site.wp_postmeta] status: OK
[site.wp_posts] status: OK
[site.wp_term_relationships] status: OK
[site.wp_term_taxonomy] error: Table upgrade required. Please do "REPAIR TABLE `wp_term_taxonomy`" or dump/reload to fix it!
[site.wp_terms] status: OK
[site.wp_usermeta] error: Table upgrade required. Please do "REPAIR TABLE `wp_usermeta`" or dump/reload to fix it!
[site.wp_users] error: Table upgrade required. Please do "REPAIR TABLE `wp_users`" or dump/reload to fix it!

Running those SQL queries on the appropriate database in phpMyAdmin fixed the problem. I don’t know whether the hosting company upgraded the database, or something happened with the automatic WordPress upgrade system, or if something else caused the problem.

[Update] There were a bunch of other errors that cropped up afterwards with the White Screen of Death; I had to call the hosting company to sort out the server-side errors causing those. It’s possible those errors were the original cause of the database problems, whatever they were.

/* ]]> */