Migrating from WP-Syntax to PrismJS

WP-Syntax was a great syntax-highlighting plugin for WordPress. However, development had ceased, and it had not been updated for a very long time. While it is not broken per se, it didn’t work with Jetpack’s markdown support, so I stopped using it on the site and started using a different plugin. With the introduction of the Gutenberg editor, I started looking again for a plugin that would allow me to easily highlight fenced code blocks (this feature worked in the old editor with SyntaxHighlighter Evolved but isn’t supported in Gutenberg). Realizing that I don’t want three syntax-highlighting plugins enabled simultaneously, and not wanting to have an abandoned plugin enabled, I decided to migrate all the posts from WP-Syntax to a new solution.

The new solution I chose was PrismJS. I decided to use it directly (without a plugin), as it highlights by default all the <pre><code class="language-..."> constructs (which is what markdown produces as well), and I didn’t want (yet again) to use plugin-specific shortcodes like before, which would require migration when the plugin eventually stops working.

WP-Syntax used the <pre lang="...">code goes here</pre> construct. Furthermore, it took care of HTML-escaping everything inside the <pre> tag. So the migration solution would be to rewrite the <pre> tags to <pre><code> constructs, HTML-escape the code inside the pre tag, and finally remove any leading newlines. I wrote it to work on dumped SQL tables, as that seemed easiest. The flow is

$ mysqldump --add-drop-table -u USER -p blog wp_comments > wp_posts.sql
$ python3 < wp_posts.sql > wp_posts_updated.sql
$ mysql --user=USER --password blog < /tmp/wp_posts_updated.sql
#!/usr/bin/python3

import re
import html
import sys

def convert(fin, fout):
    for line in fin:
        # Each post is in a single line
        # <pre><code> doesn't ignore the first newline like <pre>
        replaced = re.sub(r'<pre lang="(.*?)">(?:r)?(?:n)?(.*?)</pre>', replace_and_escape, line)
        print(replaced)
        if line != replaced:
            print(line, replaced, sep="n============>n", file=sys.stderr)


def replace_and_escape(matchobj):
    language = matchobj.group(1)
    # We don't escape quotes because it's unnecessary and it would mess up the
    # SQL escaping
    content = html.escape(matchobj.group(2), quote=False)
    return r'<pre><code class="language-{}">{}</code></pre>'.format(language, content)


if __name__=='__main__':
    convert(sys.stdin, sys.stdout)

Google AdSense for WordPress – No Plugin Needed

Adding Google AdSense ads to your WordPress blog was a tedious task. Either you needed to manually modify your theme, or you had to use a plugin, such as Google’s own AdSense plugin. Even then, placements were limited, and handling both mobile and desktop themes was complicated at best. Recently, two things have changed: Google retired the AdSense plugin and introduced Auto Ads.

At first, the situation seemed like it had turned for the worse. Without the official plugin, you had to resort to using a third-party plugin or manually placing ads in your theme. But Auto Ads made things much simpler. Instead of having to manually place your ads, you can let Google do it for you. It works great on both desktop and mobile themes.

The easiest way to enable Auto Ads is by using a child theme. First, you need to get the Auto Ads ad code. Next, in your child theme’s functions.php, add the following lines, making sure to replace the javascript snippet with your own.

// Add Google AdSense
function my_google_adsense_header() {
?>
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<script>
     (adsbygoogle = window.adsbygoogle || []).push({
          google_ad_client: "ca-pub-4066984350135216",
          enable_page_level_ads: true
     });
</script>
<?php
}
add_action( 'wp_head', 'my_google_adsense_header');

Google Analytics for WordPress

To set up Google Analytics tracking for WordPress, you don’t need any third-party plugin. It can be easily done using a child theme. A child theme is code that modifies the current theme in a way that won’t interfere with future upgrades. To enable Google Analytics, start by creating a child theme using the official documentation.

Now, you need to get your Google Analytics tracking code. Over the years, the tracking code has had a few different versions. You should make sure you are getting the latest tracking code, which currently looks like:

<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-380837-9"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'UA-380837-9');
</script>

To get the tracking code, follow the instructions on this page.

Now, we add the tracking code to each page using the child theme. In your child theme’s directory, edit the functions.php file and add the following lines. Replace the tracking code with the one you acquired.

// Add Google Analytics tracking
function my_google_analytics_header() {
?>
<!-- Global site tag (gtag.js) - Google Analytics -->
<script async src="https://www.googletagmanager.com/gtag/js?id=UA-380837-9"></script>
<script>
  window.dataLayer = window.dataLayer || [];
  function gtag(){dataLayer.push(arguments);}
  gtag('js', new Date());

  gtag('config', 'UA-380837-9');
</script>
<?php
}
add_action( 'wp_head', 'my_google_analytics_header');

This adds the tracking code to the <head> of every page.

WordPress.com Login Loop

Sometimes, when I try to use certain functions on wordpress.com, I get redirected to a login page. After I sign in, I get redirected again to the same login page. This repeats in an endless loop. It usually doesn’t bother me, as I self-host my blog, but for some things, like the yearly annual report that came in about two weeks ago, it does bother me. I looked into the matter, and the issue turned out to be due to blocking third-party cookies. To resolve the endless login loop, you need to add https://wordpress.com (note the https) to the exception list of accepted third-party cookies (in Firefox, it’s under Preferences -> Privacy -> Exceptions).

Dealing with Spam – Follow-up

In the beginning of June, I wrote about the rising number of spam missed by Akismet. The main issue was a noticeable increase in the number of spam messages that get through Akismet, which is kind of the de-facto spam filter for WordPress. Twice a day, on average, I had to manually mark comments as spam, which really got under my skin. After writing that post, I looked at a number of solutions.
Continue reading Dealing with Spam – Follow-up

Something gone wrong with Akismet?

Akismet is a great spam-filtering service for WordPress that did wonders for my blog. Actually, it’s quite generic and can be used with any commenting service, for example with Trac (I used this for Open Yahtzee’s Trac before reverting back to SourceForge’s new ticket system). For a long time, Akismet allowed me to blog without worrying much about spam, as it hardly missed any – usually fewer than 5 spam messages a month. But something went wrong in the last three months, as can be seen in this chart:

spam_chart

As you can see, the number of missed spam messages increased rapidly from February to May (more than 15-fold), while the number of overall spam messages decreased. I have to manually mark the missed spam, and I really can’t say why some of them are missed. They are as spammy as always and surely not unique in any sense.

Although it’s not a deluge of missed spam, I really don’t like dealing with it, so I am considering adding CAPTCHA to supplement Akismet. This will also help with my backups, because Akismet keeps all the spam messages it flags for 15 days, which means that unfortunately I back up more than 20,000 spam messages each week (hopefully, one day I’ll find a good use for them).

Has something gone wrong with Akismet? Do you experience the same problems?

Incremental WordPress Backups using Duply (Duplicity)

This post outlines how to create encrypted incremental backups for WordPress using duplicity and duply. The general method, as you will see, is pretty generic, and I’ve been using it successfully to back up Django sites and MediaWiki installations as well. You can use this method to make secure backups to almost any kind of service imaginable: ftp, sftp, Amazon S3, rsync, Rackspace Open Cloud, Ubuntu One, Google Drive, and whatever else you can think of (as long as the duplicity folks implemented it :-)). If you prefer a simpler solution, and don’t care about incremental or encrypted backups, see my Improved FTP Backup for WordPress or my WordPress Backup to Amazon S3 Script.
Continue reading Incremental WordPress Backups using Duply (Duplicity)

WordPress Administration over SSL on Lighttpd

In this tutorial, we’ll walk through the steps of enabling SSL (https) for the WordPress admin panel when using Lighttpd as a web server. The tutorial consists of two stages: the first is enabling SSL at the Lighttpd level, and the second is at the WordPress level.


Continue reading WordPress Administration over SSL on Lighttpd

Improved FTP Backup for WordPress

This script backs up both the database and files of a WordPress blog to a remote FTP server (while keeping a local copy). It’s an update of my WordPress Backup to FTP script. The main changes are auto-detecting database settings and better support for caching plugins (specifically WP-Cache). The new version makes it easier to back up multiple WordPress blogs to the same FTP server.
Continue reading Improved FTP Backup for WordPress