Mostly about my amusement

Tag: WordPress (page 3 of 13)

Thank you #wpmom for everything

kim-parsell-is-now-following-you

I can’t remember when I first started interacting with #wpmom Kim Parsell. I’ve been looking and the earliest I can find was an email from April 26, 2012 saying that she was following me on Twitter.

Hundreds of tweets and many emails later and it sure seems like it was much longer than that. She had that effect on you and on October 25th, 2014 I finally got to meet her in person at WCSF.

She was so down to earth and so real. Nervous too, she was going onto tape as the Docs lead for explaining the Codex and getting involved in that team. When that video was taken I was near the podium doing the thumbs up thing before and after her presentation. She had nothing to worry about and she did fine.

The WordPress community is volunteer driven and we all focus on those things we are individually interested in. For me I like to provide support even if it’s just a “Hey, try this plugin it may help you out” reply in the forums. That’s an easy way to get involved and takes very little time.

Kim did so much more than that. She was an active and key member of the Docs team and contributed to WordPress core. She downplayed it but she was a member of and a huge person to the whole support team. She collaborated with so many people. The tag #wpmom was one that she embraced and it was true, she really was like the Mom to all of us. On my last day at WCSF I walked over to sit with her and see how she was doing. I had to, I told her I would. We talked about meeting again at other WordCamps and I wanted to introduce my kids to her.

Now that won’t happen and I feel awful. When I heard the news about Kim’s passing I was shocked. I kept telling myself that she’s just taking a break or a vacation. That’s what I told myself till the last minute.

I feel so small right now. But interacting with her online made me a better person. Collaborating with her and others is amazing and even small contributions are valuable. I got to meet her in person and I’m so grateful for that. She made me feel involved and important. I’ll miss her and her encouragement but I can’t mope about it. That’s not something wpmom would approve of.

I Am NGINX! (And So Can You!)

A few months ago I switched my Apache2 installation for this blog from mod_php to php5-fpm. Using Ubuntu LTS this was as simple as running apt-get remove libapache2-mod-php5 ; apt-get install php5-fpm and adding /etc/apache2/conf-available/php5-fpm.conf with just a few lines.

I activated that config and it worked! Mostly. There was some more than that but it wasn’t hard. I did this because I wanted to play with mod_pagespeed and I needed php5-fpm to do that.

It didn’t exactly work as well as I’d have liked.

My Apache2 installation had become temperamental.

I couldn’t get the number of workers right and there was some sort of condition that was causing php5-fpm to break and generate 500 errors. The logs didn’t tell me what was going on and the problem was outside of WordPress. Restarting Apache2 every couple of days worked but that just sucked.

I like server based solutions that just work. This one was effecting all 7 sites in my network including Lily’s store.

This was a great time to switch to nginx!

I could not get my multisite /files/ and blogs.dir working on nginx. It just wasn’t doing what I thought it should and I think it was because of my 7+ years of carried database options and junk.

When I tried fix it I found many other things broken on my installation. So I ended up creating a brand new multisite installation, imported via XML all of the sites (I only had 7 so that wasn’t too bad) and after it all worked I globally searched and replaced all the references of the new sites with the old.

That took me almost a week. I worked on it after hours, November is a busy month at work. I did get Lily’s site working first so there’s that. I may write a post about that exercise. The search and replace worked well and so did the DNS part.

Here’s my Apache2 .htaccess bits and the nginx conf replacements. All of the nginx bits are in one file.

Redirecting an old URL to a new  one

Years ago my installation URL was different and I used a ReWriteRule to send visitors to the right place.

RewriteEngine on
RewriteCond %{HTTP_HOST} wp\.dembowski\.net [NC]
RewriteRule (.*) https://blog.dembowski.net/$1 [R=301,L]

This is long gone but incase you need it, here you go for the nginx equivalent.

server {
        listen 80;
        server_name wp.dembowski.net;
        return 301 https://blog.dembowski.net$request_uri;
}

Send all URLs to the SSL version (with exceptions)

I want WordPress to be SSL based but I am comfortable with my RSS feed being available via plain http.

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} blog\.dembowski\.net [NC]
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} !^/feed/$
RewriteCond %{REQUEST_URI} !^/index\.php$
RewriteCond %{QUERY_STRING} !^feed=rss2$
RewriteRule ^(.*)$ https://blog.dembowski.net/$1 [R=301,L]
</IfModule>

On nginx that works out to these lines in my server section for plain http.

location /feed/ {
        try_files $uri $uri/ /index.php?q=$uri&$args;
}

location / {
        return 301 https://$http_host$request_uri;
}

Everything get’s handled by the “location /” part and exceptions like “/feed/” go above those lines. If I had any other exceptions then they would go between the two.

SSL all and SPDY

In my server section for the SSL based version, I have these lines.

listen 443 ssl spdy;

The nginx package I’m using is compiled to include SPDY 3.1 support. I haven’t put back PageSpeed but SPDY is fun to play with.

With Apache2 I used mod_ substitute change my http references to https in the HTML output. With nginx I use the HttpSubsModule.

subs_filter_types text/css text/xml;
#
# http host substitution for https versions
#
subs_filter 'href=\'http://$http_host/' 'href=\'https://$http_host/';
subs_filter 'href=\"http://$http_host/' 'href=\"https://$http_host/';
subs_filter href='https://fonts.googleapis.com href='https://fonts.googleapis.com;
#
# make http into protocol-relative URLs
#
subs_filter src=' src=';
subs_filter src="http: src=";

The Google Fonts was put in because one of my sites use it and the SSL page broke until I put that there. And I don’t yet have Jetpack’s infinite scroll working quite right. Meh.

While I’m at it, you should always set HTTP Strict Transport Security to tell web browsers not to downgrade from HTTPS to HTTP.

In Apache2 that’s this line.

Header always set Strict-Transport-Security "max-age=31536000; includeSubDomains"

In nginx in your server section add this line.

add_header Strict-Transport-Security "max-age=31536000; includeSubDomains";

Redirecting client IPs

Sometimes I just don’t want some people to visit my site and 301 them to a YouTube video. IP blocking is a temporary solution but in Apache it’s easy.

RewriteCond %{REMOTE_HOST} 192.168.111.75 [OR]
RewriteCond %{REMOTE_HOST} 10.22.33.230 [OR]
RewriteCond %{REMOTE_HOST} 172.16.11.132
RewriteRule .* https://www.youtube.com/watch?v=NN75im_us4k [R=301,L]

Easy to accomplish with nginx with these lines. The 403 isn’t the same code but the results are the same.

location / {
        include /var/www/vhosts/block_ip.txt;
        try_files $uri $uri/ /index.php?q=$uri&$args;
}

The block_ip.txt file contains these lines.

# Deny these IPs
error_page 403 https://www.youtube.com/watch?v=NN75im_us4k;
deny 192.168.111.75;
deny 10.22.33.230;
deny 172.16.11.132;
allow all;

So no .htaccess live changes?

With Apache2 when you make a .htaccess file change it is live immediately. Each http request that hits the server parses the content of that (and other) files.

That’s not true with nginx and any configuration changes need a “service nginx reload” as root or via sudo. I don’t make frequent configuration changes so that’s not a problem for me.

What’s with the Stephen Colbert thing?

I like Stephen Colbert. You don’t get the reference for the blog post title do you?

Remove shortlink URLs from comments

Or remove them from anywhere, though I’m not sure why you’d remove shortlinks from your own author’s posts.

I’ve written a small plugin that will filter your comments using preprocess_comment which is a useful filter comment data before it’s committed to your database. The other toys I used are wp_extract_urls and wp_remote_head to make http head requests to web sites.

The plugin works like this: you feed a function a URL and it gives you back a URL but with shortlinks you get the real destination. It uses wp_remote_head() to make an http HEAD request and looks for the location header.

If it finds that header then it recursively calls itself to get real destination up to 5 requests. After 5 requests the URL is replaced with the # sign. If it doesn’t find that header then the original URL is returned.

Depending on your site that can be a lot of URLs and to cache those results I create transients for those URLs. The next time in a 12 hour window that URL is tested then WordPress will pull the data from the transient.

I’ve never used transients and I’m not sure this is a good idea or not. But if you need to eliminate shortlinks then this plugin might do it. Also this parses all URLs in the post or the comment and that’s probably not necessary. A simple check can be put in to see if the URL is on a list of shortlink providers and ignore all the rest.

You can download the plugin from this Gist page.

Once you’ve downloaded it save it to your wp-content/plugins directory as short-links-begone.php and activate the plugin in your WordPress dashboard. This plugin will not change any post data or old comments. It will modify new comments when they are submitted.

No more @import for me

Well, at least not for current WordPress child themes.

I like child themes and always recommend that people use them instead of modifying any WordPress theme directly. Using a child theme makes your changes belong to you and they won’t get erased when the original theme gets updated.

I’ve told people to use something like this in their child theme’s style.css file.

/*
Theme Name: Sorbet Child theme for Mostly Harmless
Theme URI: https://blog.dembowski.net/
Description: Child theme for the Sorbet theme
Version: 0.1
Author: Jan Dembowski
Author URI: https://blog.dembowski.net/
Template: sorbet
*/

@import url("../sorbet/style.css");

/* Start your custom CSS after this line */

See that @import line? That had previously been required if you wanted to inherit the parent theme’s CSS. At the moment my child theme does not have that @import anymore and instead I’ve created a functions.php file with these lines in it.

<?php

function mh_sorbet_child_style() {
        wp_enqueue_style( 'sorbet-parent-style', get_template_directory_uri() . '/style.css' );
        // wp_enqueue_style( 'sorbet-child-style', get_stylesheet_uri() );
}

add_action( 'wp_enqueue_scripts', 'mh_sorbet_child_style' , 5 );

Which really is a more WordPress way to do it. I added a function mh_sorbet_child_style() where I first queue up the parent theme’s style.css and then queue up the child theme.

Notice how I commented out the second line? The parent theme already queues up the current theme’s style.css file and in my case that is sorbet-child/style.css. In my child theme I do not need to queue it a second time as it’s not necessary.

But I do want to ensure that the parent theme is queued up earlier than the child theme CSS. That’s why I add the wp_enqueue_scripts with a priority of 5 instead of the default 10. That should always load the parent CSS first. If the theme does not queue up it’s style.css that way then I would un-comment out that line.

Just as before, any new CSS will go into my child theme’s style.css file.

 

I may have broken my Feedburner feed

After I converted my WordPress install to 100% SSL I noticed that my own feeds in Tiny Tiny RSS were not updating. Years ago I forwarded my RSS feeds to Feedburner and 301 redirects from https://blog.dembowski.net/feed/ https wasn’t working.

I can’t even remember why I used Feedburner. I’m pretty sure I turned it on in a moment of “What’s that button do? *Monkey pushes button*”.

I’ll keep testing but eventually I’ll disengage Feedburner and just use https://blog.dembowski.net/feed/ instead.

Edit: This work around seems to fix it.

<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} blog.dembowski.net [NC]
RewriteCond %{SERVER_PORT} 80
RewriteCond %{REQUEST_URI} !^/feed/$
RewriteCond %{REQUEST_URI} !^/index.php$
RewriteCond %{QUERY_STRING} !^feed=rss2$
RewriteRule ^(.*)$ https://blog.dembowski.net/$1 [R=301,L]
</IfModule>

The part starting at line 5 is where I added conditions so that the SSL 301 redirect will be ignored.

Why not use SSL and be done with it?

On the Internet there has been talk about Google and SSL based web sites. Apparently you may get a small boost if you switch to https. I myself doubt that (I’m jaded that way) and the additional SSL math will slow down busy sites a little. But I don’t get enough traffic to care really and I do like to play. This seems easy enough to do.

I Like Server Based Solutions and I Cannot Lie

I use WordPress multisite and on my web server I have a valid SSL certificate installed. I’m already using Apache’s mod_substitute to modify https://blog.dembowski.net/ to https: before it get’s sent to the browser for my SSL site.

Why not switch to SSL and be done with it? I could have used a tool to change all the WordPress database references to https but I’m running multisite and I wanted to be a little more site specific so I added this to my .htaccess file above the WordPress part but below the “Get Lost, I don’t like you” part.


<IfModule mod_rewrite.c>
RewriteEngine on
RewriteCond %{HTTP_HOST} blog.dembowski.net [NC]
RewriteCond %{SERVER_PORT} 80
RewriteRule ^(.*)$ https://blog.dembowski.net/$1 [R=301,L]
</IfModule>

So far it hasn’t broken anything and is limited to my this one and not the other sites. I’ll keep an eye on it but there’s no reason for me not to leave it that way. I like server based solutions but for other people a HTTPS plugin may be an easier way to go.

The only downside is that I will need to maintain my SSL certificate but I plan to do that anyway.

So this means I wear a tin foil hat?

Not really but it does mean in most cases people visiting my site will get the traffic encrypted between my site and their browsers.

*Adjusts Tin Foil Hat™ and skips conversation about  SSL transactions and man in the middle interception*

It’s more a concern that someone will have some key logger or other hack installed on their machine.

Sniffing unencrypted data on the Internet is easy. Doing so for encrypted SSL traffic is more difficult. It would require the Bad Guy or Spook to have access to the private certificate issued by the certificate authority. Or exploit a server bug and harvest the SSL private certificate from the web server. That would never happen right…?

If your interested in how it all works then start with this Wikipedia article on TLS. This Digicert article is good too and may be easier reading. In the meanwhile anyone coming to my site will get redirected to the SSL based version.

Excerpts and not full content, but only sometimes

WordPress filters and actions remains one of my favorite features. There is so much that you can easily manipulate without modifying a theme’s files.

For example: on my front page I like the latest published post to show the whole content with a featured image if there is one. For the rest of the articles I want to display the excerpt and no featured image. This is the same on the front page and subsequent pages.

One way to do this is to create a child theme and modify the PHP to get the effect you like. There’s a few reasons why I don’t like that option.

  1. Child themes are fun and I always recommend users create them. But I’m bad at maintaining them when the parent theme is updated.
  2. My CSS is just awful and I’m pretty sure I’d break the responsiveness of my site.
  3. Filters are cool! I can use this code in a plugin.

Filter the_content

I took a shot at making my own filter but a quick search found that Justin Tadlock had written a really good post on the topic already in 2008. I use that code in my function but added a few lines.

// Get the ID of the last published post
$mh_last_id = wp_get_recent_posts( array( 'numberposts' => '1' ,
     'post_status' => 'publish' ) )['0']['ID'];

// Get the post format. If the post is a standard format then the value will be false
$mh_post_type = get_post_format();

I do not want to show an excerpt for the latest post  and only want to modify standard post formats. Anything else I want to skip. The reason I only want to play with standard format posts is that other post types break horribly when I force the excerpt this way.

Except for adding to the conditional statement, the whole function is copied from Justin’s post. He writes great code and explains it much better than I do.

// If is the home page, an archive, or search results and not the last post and is a standard format
if((is_front_page() || is_archive() || is_search()) and $mh_last_id != get_the_ID() and !$mh_post_type )

That’s a little ugly to look at but it does the job.

What about the featured image?

In the past when I wanted to hide the featured image in a child theme I would use CSS like so.

.ryu-featured-thumbnail, .attachment-ryu-featured-thumbnail, .wp-post-image {
     display: none;
}

Which works but is a little heavy handed. My WordPress installation still sends the HTML for the featured image and the browser still pulls that image. The end user just doesn’t see it because it’s not being displayed.

I don’t want to remove featured image support from the theme and I don’t want to send that HTML either. Thanks to the post_thumbnail_html filter I don’t have to.

add_filter( 'post_thumbnail_html', 'mh_post_image_html', 10, 3 );

function mh_post_image_html( $html, $post_id, $post_image_id ) {

// Get the ID of the last published post
$mh_last_id = wp_get_recent_posts( array( 'numberposts' => '1' ,
     'post_status' => 'publish' ) )['0']['ID'];

if ( (is_front_page() || is_archive() || is_search()) and $mh_last_id != get_the_ID() ) {
     $html = '<!-- Featured image not displayed in excerpt -->';
     }
return $html;
}

This code checks if we’re the first post and replaces the post_thumbnail_html with a simple HTML comment.

Child theme or plugin?

This code works either way. At the moment I am using this in a plugin but the whole thing can be implemented in my child theme’s function.php file.

It belongs in the child theme because I’m playing with the presentation and that is theme territory. Editing a copy of content.php in the child theme directory would be more theme’ish but I like filters. Filters are cool.

I’m not good at keeping my child theme changes in sync with the parent theme so using a filter lets me just play with the results and not mess with theme files. In a plugin or the child theme’s functions.php file the filters still work the same.

The replacement VPS didn’t go BOOM!

Yesterday I moved my WordPress network from one VPS in Chicago to Atlanta (different VPS hosting company). I like using a VPS because it maintains my illusion of being in control of my server.

*Drinks more coffee*

Surprisingly it went well. Except for missing a couple of PHP modules I had no problems and the site has been stable overnight.

If you plan to do this then give this Codex article a read. Of course I didn’t read it myself, it’s much more fun for me just winging it.

Create and configure my new VPS

I installed an image of Ubuntu 13.04 and made sure SMTP was configured to work. Apache2, PHP, mysql and mod_ssl were added and activated as well.

That was a surprise for me. The default image installs a ton of stuff that I don’t think I’ll ever need or want. I would have preferred to use a 14.04 LTS image (not available, too new) but that one is still maintained so it’s all good.

Creating the new empty database was straight forward. I used the same database name and user from the original VPS setup. Configuring the vhosts was just a matter of copying the old config files and making sure the certs and directories are all preserved.

Set DNS TTL on stun

My default DNS TTL (time-to-live) is 1800 seconds. I wasn’t sure if this would go well or not so I made the TTL 300 seconds (5 minutes). I didn’t change any IP addresses but if I broke something and couldn’t fix it then I was looking at only 5 minutes for it to come back to life.

Copy the files and database

My WordPress network has around 1.4 GB of file data from the last 7 years or so and the mysqldump was about 70MB . The file copy was just scp -r and the mysqldump command was just for that one network database.

Importing the database was just

zcat dumpfile.sql.gz | mysql -u name -p databasename

Once that was all done I updated my DNS IP and waited.

And I waited. And waited some more.

I could see in my access log that my new site was getting hits but I was still hitting my old web server (I was tailing the old logs in another windows) well after 5 minutes.

What the heck? It’s DNS. Setting the TTL just works. Except when it doesn’t.

I was using Google Chrome and that has it’s own application level DNS cache. It has a DNS cache that apparently doesn’t honor the TTL on the record.

Once I cleared that cache then I could see myself hitting the new IP address.

Nothing broke! Fantastic.

Next steps

Once I’ve confirmed that I have moved everything off the old VPS and onto the new then I’ll rebuild the old one and might re-do this whole exercise in the other direction. I’m sure the unstable nature of the old one is due to some dumb thing I did code I installed that’s running amok.

In the meanwhile I’m going to enjoy some nice stability and uptime for my site.

Note: The CC image above was a result of my typing “controlled implosion” into the WP Inject WordPress plugin. It’s a very cool plugin for finding CC images and I plan on leaving a review on WordPress.org sometime.

Featured image photo by Savannah River Site

Favorite new WordPress 3.9 feature

Copying and pasting from Microsoft Word directly into the Visual Editor is my new favorite thing in 3.9 beta. I just tried it on Lily’s store WordPress site and it worked alright. This is a fortunate side effect of 3.9 getting a new version of TinyMCE.

I know, that sounds anti-climatic even a little mundane given the great enhancements that 3.9 will be delivering. But I occasionally (once a month) have this conversation.

Them: How can I copy this Word document into WordPress?

Me: First select the text and paste that into notepad. I like notepad++ myself.

Me: Then you take the text you just copied into notepad select and copy it into the Visual Editor. Again.

Me: Make sure you copy from notepad. Bad things will happen if you paste that into the Visual Editor directly from Word.

Me: Then you apply the styling such as bold, underline, etc. To that text. For titles I like to use the <h3> tag myself.

Me: No, that layout thing you did in Word won’t work.

Me: Images? If you use the Snipping Tool then you can save that image to your hard disk.

Me: Once you’ve done that, upload that into the media library.

Me: Then you can insert it into the WordPress post. The image I mean, I usually go with centered and no link.

Them: Zzzzzz Wha-? What we’re we talking about??

I myself don’t like the idea of users creating content for WordPress outside of WordPress but I’m told I’m special. Apparently “regular” users (yes I’m doing the “air quotes”) such as my wife and some siblings use Word that way.

Lily creates flyers for wine tastings once a week. Right now she has to wait for me to create the event on the WordPress site (thank you Modern Tribe! that’s a great plugin) then cross post it to the company Facebook page. If I can show her how to just paste the content into WordPress to create the event then she can deliver the post sooner.

Also that means I’ll have one less thing to do each week.

Next I have got to test out dragging images into the Visual Editor to upload them that way. That’s got to improve “regular” users workflow too.

Let’s play a game called SERP

On the support forums occasionally (OK today) someone will ask that a post be edited to remove a link or company name for SEO reasons. Unless there’s a good reason for that (and SEO isn’t) then it just isn’t done. There are millions of posts on those forums; can you imagine if a small percentage of members asked for posts to be edited that way?

It’s not always necessary to edit The Interwebz

I am not a web front end developer. I don’t do “SEO”, I don’t at this time have any advertisements on my site. I post to my self-hosted WordPress blog for my own amusement and occasionally the amusement of my friends.

But just for giggles, let’s do a search on Google for my name. I wonder what comes up?

seo-games-jan-dembowski

Huh. That’s weird.

The first hit is my Twitter page, followed by my Make/Support author page, a Polish biologist then a general who both died before I was born (no relation). Then there’s some images (hey, 3 of those are me!) and then my WordPress site. Ah, there’s my Flickr page. I was worried about that not being there.

There is nothing on that search engine results page pointing to the WordPress forums. That’s a shame. I’ve got *looks WOW* 10,772 posts in the forums. That’s not necessarily a lot by the way.

How did that happen?

Again I am not into “SEO” and I haven’t done anything to impact that SERP. I even had to look up what SERP meant to make sure I’m using the term correctly.

But my guess is that the results happened that way because those links are pertinent and each of those links have content that is updated. That’s all there is to it.

  • I tweet everyday non-stop so it’s no wonder that popped up as the first hit.
  • I post to make/support at least once a week so there’s that.
  • Links 3 and 4 are cool and I like that my name is notable (even if the original spelling was Dębowski, ę is pronounced /ɛm/, w is a v sound, look it up).

The important thing is that I produce content and that’s why when someone looks up my name you get sites that I actually update.

So “SEO” magic isn’t real?

There are people who advertise and I assume make a living on SEO work and I am sure they know what they are doing.

If I had a site that I was selling something then I may be concerned that my actual site is 6th down from the top (skipping the images). If I were selling something then perhaps I’d use an SEO plugin. I’d also update my actual site more frequently.

Even without my doing anything special a search for my name shows the links that I expected to see.

My advice to people who want links removed from the forums or anywhere remains the same: if you don’t like your search engine results then change them. Produce original content on your own site. That’s really all there is to it.