Wordfence: Block Bad Logins

There are dozens of computers trying to login to this site over the course of a day. It’s not an important site, not a site that’s chock full of credit card information, and not a site that matters to anyone but me. (Yes, I put out my lower lip while typing that last one.) Nonetheless, the login attempts continue.

The attempts are coming from bots… computers that are infected with malware that puts them under the direction of various command and control servers. They scan, look for WordPress sites, and try to login. If they succeed, they let someone upstream know, and then push malware onto the system.

I have blogged about this before. I’m using WordFence as one of the defense layers for this system. It locks out anyone who tries to login with incorrect information. The login settings are:


lick to enlarge

Converting a Drupal site to WordPress


I recently converted this site from Drupal 7 to WordPress. Here’s how.

1. Move data from Drupal’s database into a WordPress database.

Liran Tal has posted a PHP script on Github that does the heavy lifting. Read the instructions carefully. I probably should have read them a couple more times.

wp-drupal-logos2. Validate the data conversion

Almost all of the content of the Drupal site was converted into the page type on the WordPress site. I used a bit of SQL to switch them to posts, then hand fixed the 5 or 6 that really should have been pages.

The SQL is

update wp_posts set post_type='post' where post_type='page';

3. Get the images and other media

This part involved several steps.

First, I copied all media files from “/sites/default/files” on the Drupal site into “/wp-content/uploads/” on the WordPress site.

Second, I ran a script to go through all posts and replace all occurrences of “/sites/default/files” with “/wp-content/uploads/”. Searchreplacedb2.php is handy script for search/replace tasks like this. When this was done, the posts displayed images, but the media library was empty, at least according to the media button on the WordPress dashboard.

Third, I used a WordPress plugin, Add To Server, to tell WordPress about all those files I dropped into the uploads folder. Here’s a handy “how to” on that.

Update 1:  I installed the Simple 301 Redirect plugin to handle any changes I missed and to deal with all the links that Google already had it its index.  I redirect “/sites/default/files/*” to “/wp-content/uploads/*” and added a few more redirections handle a few cases where I changed the names of posts and pages.

4. Housekeeping

I set the theme to TwentyFourteen just to get things going. I had to create the main navigation menu using the menu editor, set a home page and a blog page, and do the other usual stuff that comes with creating a WordPress site.

One of the frustrations is that Drupal’s editor (CKeditor) handles character sets differently that WordPress’ editor, TinyMCE. The symptom of this is that the page looks OK when viewing normally, but is truncated in when viewing.* Typically, there’s an invisible character that TinyMCE abhors. My short term solution is to flip the editor into HTML mode, copy, and paste it into a text editor. I then do a search on the first character that TinyMCE doesn’t like and replace it with a blank. Copy and paste back into TinyMCE, click Preview, and see if it fixes it. If not, find the next place and continue.

The long run solution is to make a list of all of the characters, some invsible, some not, and write a bit of SQL to convert each into its proper relacement.

Update 2: I hosed something in the database.  I’m not sure what. When I did the conversion again, I didn’t have this problem.  Moral:  Be prepared to do things two or there times until  you get it right.

5. Theming

I wanted a minimal theme that would get a responsive result with the least effort. I’ve been using underscores (_s) for a long time and wanted to use bootsrap for responsiveness. Luckily, Themekraft developed a started theme called _tk_master, that mashes together (in a very appropriate fashion) bootstrap and underscores.

6. To Do

So, about six hours after starting, I have a working website with a reasonably readable theme. There’s still a lot to do.

  • Build a visual gallery of developed sites.
  • Change the footer to three column footer.
  • Working with IrisB to develop a non-grayscale color pallette.

Book Review: WordPress 3.7 Complete

WordPress 3.7 Complete link to publisher siteWordPress 3.7 Complete
Authors: Karol Krol, Aaron Hodge Silver
Packt Publishing: http://bit.ly/1iLUPME

WordPress 3.7 Complete offers, well, a complete explanation of WordPress. The first chapters, directed at WordPress users, is a patient but not “for dummies” walk through what you need to know if you own a WordPress site.

Chapters 1 through 5 are a great introduction to users of WordPress. If you’re a professional WordPress developer, buy your clients a copy of this book and do their training only after they’ve read those chapters.

There is one unfortunate aspect to this book. Almost as soon as it was published, WordPress 3.8 was released. All of the information is still current and directly applicable; the book has lost no value with the update. The only real affect is that some of the illustrations of the WordPress dashboard are no longer what the site’s owner will see. The value is still there. There are also enough links to the WordPress Codex and other the publisher’s own site that the content should be current through the life of 3.8.

The book starts off where we all start off: Terminology and “What is WordPress,” and what’s the deal with WordPress.com and WordPress.org? As it gets more into the creation of your first site, I like that it starts with content and worries about theming later. I see way too may people picking a theme then worrying about content. The step by step instructions for posting content will get the most technophobic user posting content fairly quickly.

Differentiating pages and posts waits until Chapter 4, as do menus, headers, and other customization options provided in most themes. This chapter also includes the media library and image galleries. It would be nice if this chapter also included discussion of the video shortcodes; users often seem confused about embedding YouTube and other video content.

Chapter 6 talks about choosing and installing themes and offers some good advice about choosing safe themes and the purpose of themes. “The trick of choosing a theme for your site is to understand its purpose and make your decision …. on the thing you need the theme for…” Excellent advice!

Chapter 7 gets into theme development. It’s a high level view that occasionally swoops down into code. This isn’t the book I’d recommend for serious theme developers, but it offers a good overview for people who want more insight into how WordPress works and why hiring a developer to create a custom theme is not inexpensive. The development focuses on building themes from scratch. I’d have preferred a discussion that talked a bit more about building from starter themes like Underscores (http://underscores.me) or one of the standard WP themes like TwentyTwelve. Nonetheless, by the end of the chapter, the reader (who may have glazed over at all the code) has a pretty good idea about the division of work and why things in WordPress work the way they do.

Chapters 8 is a catchall, talking about using WordPress as a podcasting platform, RSS feeds, and offline site tools. I’m not sure why that last bit is in this chapter; it seems to me that it might have fit better earlier when adding content was the topic.

Chapter 9 follows in the path of Chapter 7, getting back to areas of interest to developers. This chapter deals with developing plugins and widgets. It’s a decent overview but the widget development section lacks a discussion of what I think are two essential areas for widgeteers: Managing and storing options “the WordPress way” and providing a clean uninstall for your widget.

Chapter 10 is back to operational considerations: Running a multi-user site and multisite. I think the multi-user discussion is something that more readers will find valuable; the authors delve into questions of process and user management. These are critical areas for multi-user sites and need to be considered sooner rather than later in the development of the site.

Chapters 11 and 12 talk about my bread and butter, “Creating a non-blog website.” WordPress may have started off as a blogging platform. It’s evolving into a fully featured content management system (CMS) that can present any content on the web. The chapters also covers e-commerce, community sites, membership sites, etc. These topics are worth mention but a probably deserving of their own books. Custom post types make their appearances here. I think they might have fit better in Chapter 7 or 9.

In summary: A good book for those just getting into WordPress as users or those wondering about becoming site-builders and developers. An excellent training source for those handed a working site and told “OK, it’s yours. Start adding your content.”

Full Disclosure: I received a free epub copy of the book in exchange for writing this review. The publisher did not review or approve its contents.

Hackers, Bots, and Bores

A few minutes ago, I tweeted “It’s fun using #Wordfence to watch bots try to login as ‘admin’ to my #WordPress sites. I auto-block that ID.” And it is, although the ongoing attempts are both annoying and a waste of bandwidth.  This was a big deal a few weeks ago. In fact, the sheer volume of attempts to login as ‘admin’, over and over again with commonly  used passwords, was enough to bring down several shared hosting sites.

As a hosting server, what can you do?  It seems to me that you should monitor http traffic, looking for multiple login attempts with the ID ‘admin’ and use firewall blocks to throttle traffic from those IP addresses.  I chose to say “throttle” rather than “block” because — just maybe — there might be a real user out there struggling to remember his admin password.

As a WordPress site owner, what can you do?  First, don’t have a user named ‘admin’.  They can’t login on an account that’s  not there! Second, install the WordFence plugin.  On the options panel, enable “Login Security” with fairly agressive settings:

If you want to see if it’s effective, enable WordFence’s “Live Traffic View” and on the Live Traffic panel, click on the “Logins and Logouts” tab

If you set up your WordPress site with an ‘admin‘ user, how do you remove it without breaking the site? 

  1. Create a new user on the site that you’ll use for administrative purposes.  Make sure you give it a strong password and don’t forget to assign it the adminstrative role.
  2. Log out and log back in as the user you just created.
  3. Under “users”, select and delete the orginal adminstrative user, ‘admin’.  WordPress will allow you to reassign content posted by this user to another user.

How else do you secure your WordPress sites?



How Do You Get Started with WordPress?

Branding and Blogging with WordPress | Promoting Your Personal Brand on the InterWebsI build WordPress websites, both “regular” sites and blogs. Are you ready for a web site? Before you invest money in a blog or site, take a minute to set up a free site over at WordPress.com.

Use your new site to sketch out the content you want on your site. Then, write your content. So far, easy. Now we come to the hard part — creating new content  on a regular basis. Make the effort and get over the hump. Revise, reconsider, and restart if necessary. Once you and your blog are getting along and enjoying each other, call me to discuss things like design and functionality.

Getting started is always the hardest part. In the words of Pigpen, “Get your hands out of your pockets and turn on your web site.” Or something like that.

Hint: Use Wordle.net to profile your site. What you’re talking about and what you think you’re talking about may be two different things.

WordPress Themes: Underscores AKA _S

Selection_003_0Here we go again.  I’m feeling comfortable with creating child themes for WordPress’ TwentyTwelve theme, using it on several sites* including my own WordPress site.  Last night, at the Northside WordPress MeetupBecky Davis reminded me of a few of the problems with the TwentyTwelve approach and suggested — for the second time — that I try the Underscores theme.

So…  You’re either on the bus or off the bus.  My WordPress site may be an interesting place over the next few days on its way to brilliance or disaster.

* Recent TwentyTwelve based sites are http://threemorewishesjazz.com, http://ellenblumbarish.com, http://slneighbors.org, and a couple in development.

Dynamic sidebar height and responsive themes

1 Comment

In another post, I listed the javascript to be used in a WordPress text widget to ensure that a sidebar had the same height as a page’s content. This is a nice feature if the sidebar has a background color. When the theme is responsive, the sidebar drops to the bottom, below the main content, so it should be sized to fit its own content, not that of the main content area. All it takes is a bit of javascript that checks the current page width.

Note: This snippet uses element names based on the TwentyTwelve theme layout. If you’re using different theme, you may need to pick different elements.

<!-- this must be the last widget. It dynamically sizes the sidebar -->
<script type="text/javascript">
var divh = document.getElementById('primary').clientHeight;
var sb1 = document.getElementById('secondary').clientHeight;
document.write(" ");
if ((sb1 < divh) && (document.getElementById('page').clientWidth > 600)) {

Inserting custom PHP code into a WordPress page

WordPress is a great, highly flexible content management system (CMS), but inserting a big chuck of custom PHP code that does a lot of database manipulation can be very tricky.  Go ahead and google it… I’ll wait a minute.

I’m working on a site for a grant making organization.  The website needs to include a list of recent grantees and the ability to search the list of grants by date, amount, and/or grantee.  It was easy to include this on their old HTML and PHP site.  Making this to work in the new WordPress site was a bit of a worry.  It turned out to be a lot easier than I feared.

The site is being built using the Thesis theme. One of the very nice features of Thesis is a that it supports a custom template that can be modified programmatically. What does this mean?  On the page that will list the recent grantees, I set the type to “Custom Template”.Selection_003

The Thesis custom_functions.php file then dynamically modifies the custom template for the page in question

 function custom_template() {
   if (is_page('36') ) {  // recent grants ?>
     <div id="content">
     <div id="post-<?php the_ID(); ?>" class="post_box top">
     <?php include ('grantsdb/newgrants.php'); ?>
     <div id="sidebars">
     <?php thesis_build_sidebars(); ?>
     <?php }

remove_action('thesis_hook_custom_template', 'thesis_custom_template_sample');
add_action('thesis_hook_custom_template', 'custom_template');

The actual code to display the recent grants is in grantsdb/newgrants.php.

Thesis’ custom template customizations let me re-use the code from the old website with a minimum of fuss and did not require any modifications to WordPress at all.

Dynamic Sidebar Height for WordPress and the Thesis Theme

One of the things web designers like are brightly colored, drop-shadow sidebars that match the content height on evey web page.  Because content height depends on the content and sidebar height depends on the number and size of the widgets in the sidebar, it takes a bit of dynamic thinking.  You need to know two things:  (1) How high is the content and (2) what’s the current size of the sidebar?  Given that, the forehead slapping moment comes from finding that one can reset the CSS for an element on the fly using JavaScript.

The sidebar in question is in a DIV with the ID sidebar_1, floated to the left side of the page.  The content is in a DIV with the ID content, floated to the right  

If you find yourself with a similar problem, add a text widget to the sidebar and paste in the following JavaScript:

<script type="text/javascript">
var divh = document.getElementById('content').clientHeight;
var sb1 = document.getElementById('sidebar_1').clientHeight;
document.write(" ");
if (sb1 < divh) {