Mark on WordPress

WordPress puts food on my table.

Using PHP5 object constructors in WP Widget API

with 5 comments

Someone mentioned to me that they couldn’t use PHP5-style object constructors when using the WP Widget API. I looked into it, and it turns out it does work. Example:

class My_Widget extends WP_Widget {
	function __construct() {
		$widget_ops = array( 'classname' => 'css-class', 'description' => 'Description' );
		parent::__construct( 'css-class', 'Title', $widget_ops );
	}
	// Rest of your widget subclass goes here
}

The key is using parent::__construct() instead of $this->WP_Widget().

Written by Mark Jaquith

September 29, 2009 at 1:15 pm

Interview with Deutsche Welle on WordPress Security

with 11 comments

I recently did a short interview with Deutsche Welle about WordPress security. Listen to it here.

To expand on the topic, here are some of the details that didn’t make it into the final cut of the interview:

If your blog is compromised, you should install the latest version of WordPress, but first you should remove your old files. This is to prevent a hacker from leaving a back door (something like wp-give-hacker-access-forever.php in your WordPress directory. Just dropping the new version over the old version wouldn’t replace a new file that a hacker may have added, which is the reason for getting rid of the old files. Once you’ve done that (being careful to back up your wp-config.php and all your wp-content files), upload a clean install of WordPress. Restore your custom files. Next, look for any user accounts that weren’t there before, or that have higher access than they should. Sort that out. And lastly, scan through your theme/plugin files looking for backdoors or hidden links. This is mostly a manual process, but there are some common things to look for. Most backdoors use the eval() function, so be on the lookout for that!

The best way to keep your blog safe is to stay updated with the latest WordPress version! We’ve tried to make it as easy as possible to update (one-click!), and we have big plans for making it even easier in the future.

I’ve never had one of my WordPress blogs compromised, and I don’t do anything “fancy.” I just stay updated.

Reminder: if you’re using WordPress.com or another “hosted” blog solution, they take care of security updates for you. The only thing you need to worry about is choosing an unguessable, complex password.

Written by Mark Jaquith

September 27, 2009 at 5:24 pm

Posted in wordpress

Tagged with , ,

PHP $_SERVER variables are not safe for use in forms, links

with 48 comments

A common security mistake I see WordPress plugin authors (and PHP coders in general) make is using $_SERVER['PHP_SELF'] or $_SERVER['REQUEST_URI'] as the action of a form or part of an anchor’s href attribute. This is not safe to do, and opens your code up to XSS (cross-site scripting) exploits.

Common example:

<form action="<?php echo $_SERVER['PHP_SELF']; ?>">

Another example:

<a href="<?php echo $_SERVER['PHP_SELF']' ?>?foo=bar">link title</a>

Here are my two rules regarding $_SERVER['PHP_SELF'] or $_SERVER['REQUEST_URI'] in forms:

  • Do not use them
  • If you use one of them, escape it with esc_url()

Most uses of $_SERVER['PHP_SELF'] and $_SERVER['REQUEST_URI'] are in HTML forms. If you want the action attribute to point to the current URL, leave it blank. URI references that are blank point to the current resource.

<form action="">

If you do want to specify the action (and there are good reasons for wanting to do that, such as stripping the query string from the current URL), you must run it through esc_url().

<form action="<?php echo esc_url( $_SERVER['PHP_SELF'] ); ?>">

The same applies to links… run the href attribute through esc_url().

<a href="<?php echo esc_url( $_SERVER['PHP_SELF'] . '?foo=bar' ); ?>">link title</a>

A quick search through the WordPress Plugin Directory showed that this problem is far too common.

Updates:

Examples of URLs that could exploit this for double-quoted actions:

script.php/"%20onmouseover='alert(document.cookie)'

And single-quoted actions:

script.php/'%20onmouseover='alert(document.cookie)'

No, just using a plain old htmlentities() wrapper is not going to help! That’s still vulnerable to XSS in certain situations. If you’re not using WordPress, you should copy the WordPress escaping functions (just remove the apply_filters() portions).

If you are using the base tag, Safari will apply that base to the blank action attribute. So if you use the base tag (I never do), a blank action isn’t going to be for you. Use what you’ve been using, but escape it.

Lester Chan has a handy snippet for the form action of WordPress plugin settings pages:

<form action="<?php echo admin_url( 'admin.php?page=' . plugin_basename( __FILE__ ) ); ?>">

admin_url() takes care of escaping for you, and is an easy way to create a full WP admin URL from a wp-admin-relative URL.

Written by Mark Jaquith

September 21, 2009 at 10:50 pm

Posted in wordpress

Tagged with

TextMate WordPress Widget Snippet

with 17 comments

I love WordPress’ sidebar widgets. I also despise coding them.

I love how they let me offload menial management tasks directly to clients, avoiding all the “Change this word to another word!” e-mails. But every time I code them, it seems to involve 15 minutes of Googling, copy-pasting from a previous widget, and looking at documentation.

So I created this TextMate “snippet” to make it easier:

class ${1:PREFIX_Name}_Widget extends WP_Widget {
	function $1_Widget() {
		\$widget_ops = array( 'classname' => '${2:CSS class name}', 'description' => '${3:Description}' );
		\$this->WP_Widget( '$2', '${4:Title}', \$widget_ops );
	}

	function widget( \$args, \$instance ) {
		extract( \$args, EXTR_SKIP );
		echo \$before_widget;
		echo \$before_title;
		echo '$4'; // Can set this with a widget option, or omit altogether
		echo \$after_title;

		//
		// Widget display logic goes here
		//

		echo \$after_widget;
	}

	function update( \$new_instance, \$old_instance ) {
		// update logic goes here
		\$updated_instance = \$new_instance;
		return \$updated_instance;
	}

	function form( \$instance ) {
		\$instance = wp_parse_args( (array) \$instance, array( ${5:array of option_name => value pairs} ) );

		// display field names here using:
		// \$this->get_field_id('option_name') - the CSS ID
		// \$this->get_field_name('option_name') - the HTML name
		// \$instance['option_name'] - the option value
	}
}

add_action( 'widgets_init', create_function( '', "register_widget('$1_Widget');" ) );

Just create a WordPress TextMate bundle, create a new snippet, paste in that code and give it a trigger like wpwidget. Then just type that trigger, press TAB, and you’ll be in the first field. Type, hit TAB to go to the next field. Places where you enter the same thing twice are handled—you only have to enter it once. There are some helpful comments that’ll guide you through the rest once you’ve filled out the basics. I find that with this snippet, I can code up a new widget in a couple of minutes, tops. This is definitely going to make it more likely for me to create a widget for a client instead of just cheating and editing their theme by hand myself.

Written by Mark Jaquith

August 31, 2009 at 12:33 am

Public response to Chris Anderson’s “Free” on WordPress

with 40 comments

I got a tip that Chris Anderson’s upcoming book Free has the following to say about WordPress:

2. Feature limited (Basic version free, more sophisticated version paid. This is the WordPress model.)

  • Upside: Best way to maximize reach. When customers convert to paid, they’re doing it for the right reason (they understand the value of what they’re paying for) and are likely to be more loyal and less price sensitive.
  • Downside: Need to create two versions of the product. If you put too many features in the free version, not enough people will convert. If you put too few, not enough will use it long enough to convert.

This is most assuredly not the WordPress model. Anyone and everyone can go to wordpress.org and download a completely free, completely unrestricted, and completely feature-complete version of WordPress to run for any purpose. There is no feature limited version of WordPress.

Chris might be getting confused by WordPress.com, which is a hosted WordPress solution (the biggest one, but certainly not the only one). It is true that WordPress.com charges money for certain features, such as CSS editing capabilities. But this is completely within the rights of Automattic, the company which operates the WordPress.com service. That one company is charging for certain aspects of a hosted WordPress solution does not change the fact that WordPress itself is free/open source software and has no monetization model and no tiered versioning system.

As we talked about at SXSW, Chris, it is WordPress services that are the “freemium” portion of WordPress. We give the software away, and thus create a vibrant market for third party WordPress services (this marketplace, to quote this blog’s quite literal catchphrase, puts food on my table).

Note that it would be correct to say that this is the Movable Type model, whereby Movable Type Pro and Movable Type Enterprise get features not available in the free/open source version of Movable Type.

Update: Chris fixed this error in the electronic version of Free, and it stands to reason that future print editions will have the correction. Thanks, Chris!

Written by Mark Jaquith

June 20, 2009 at 1:27 am

Posted in wordpress

Tagged with , , ,

Escaping API updates for WordPress 2.8

with 25 comments

The WordPress escaping API functions have been updated. Escaping is a way of using untrusted text that “neuters” anything that could do damage. Escaping is used in WordPress to avoid SQL injection and cross-site scripting/script injection (XSS), among other things.

The old functions still work, so if you were using the old ones, you’re fine. The new ones just offer you an easier to remember, more concise, and more flexible way of securing your WordPress code.

Here’s an example. Say you wanted to translate a string, escape it for use in a quoted HTML attribute, and then echo it out. In WP 2.7, you’d have to do this:

<?php echo attribute_escape( __( 'Untranslated text' ) ); ?>

In WordPress 2.8, you can just do this:

<?php esc_attr_e( 'Untranslated text' ); ?>

Shorter, plus we killed the echo and the extra pair of parenthesis! But let’s break it down.

esc_ = 1, attr = 2, _e = 3

  1. esc_ is the prefix for the new WP escaping functions.
  2. attr is the context (in this case, attribute). The available contexts for 2.8 are attr, html, js, sql, url, and url_raw.
  3. _e is the optional translation suffix. The available suffixes for 2.8 are __, and _e. If you omit the suffix, no translation is performed, and your string is just returned.

More about contexts

  • attr means an HTML attribute.
  • html means text within an HTML node, but not within an attribute
  • sql is an alias to $wpdb->escape().
  • url means URLs for use in HTML attributes.
  • url_raw means URLs for use in redirects or storage in the database (does not entity-encode).
  • js means JS, for using PHP to populate a Javascript var.

More about suffixes

Suffixes work just like the function they’re named after.

  • __ translates the string and returns it.
  • _e translates the string and echoes it.
  • The suffix is optional. A blank suffix will just return.
  • Suffixes are currently only available for html and attr contexts.

Functions with translation suffixes also accept an option second parameter of a translation domain, for use in plugins.

Enjoy! Go forth and write more succinct code.

Written by Mark Jaquith

June 12, 2009 at 12:25 am

Posted in wordpress

Tagged with , , , ,

8 steps to get started as a freelance WordPress developer

with 41 comments

I’ve had a bunch of people ask me how they could get started as a WordPress developer or consultant. Rather than answer them all individually and privately, I’m putting it up for all to see.

Become involved with the development community

Join the wp-hackers mailing list. Participate when you have something useful to say, or an interesting question/problem to pose to other WP developers. Dive in at the WP support forums. Find someone with an interesting problem, and solve it for them. If it’s a notable issue, write a blog post about how to solve the issue. Which brings me to the next task…

Blog about WordPress

I’m doing this right now! Not only is it deliciously “meta,” it can raise your profile and help you connect with other WordPress developers and users. Write about a problem you solved, or a challenge you’d like to see addressed by WordPress core or a WordPress plugin. And don’t forget to blog about the plugins you write…

Write a bunch of useful plugins

This is probably the best thing you can do to get noticed by clients. Write a useful plugin and you’ll be getting business leads for years to come. You don’t have to write a really big, complicated plugin. Write something that will make using WordPress easier, more fun, more efficient, and people will remember you. It might be good to have one more ambitious plugin to serve as an example of your skills, but certainly don’t shy away from brevity. Some of the favorite things I’ve written are between 1 and 50 lines of code. Users don’t care about how big a plugin is. They just want it to serve a need. Go ahead and scratch their itch. Hint: monitor Google or Twitter for people saying “I want a WordPress plugin…” to get an idea of the sorts of needs that are currently unfulfilled.

Contribute to WordPress core

Contributing to the WordPress core software helps you in two ways. First, it provides continuing education. WordPress is constantly evolving, and you need to stay sharp! This is a great way to learn about (and influence) the direction of the WordPress codebase. Second, it raises your profile in the WordPress community (both the developer and user communities). Be sure to blog about your WordPress core contributions. Trac is a great place to start. Maintain a calm demeanor, and don’t get too big for your britches. Don’t be the person who comes in and embarrasses themselves by closing a ticket as “WONTFIX” that was opened by a seasoned developer! Watch how other tickets evolve and you’ll figure out how it works.

Stay in contact with more seasoned developers

A lot of us are busy, but we try to make time to mentor people. We’re all well-served by a vibrant development marketplace. Don’t be afraid to contact a more experienced developer for advice. The worst that will happen is that you’ll get ignored — apologies to anyone who is in my e-mail limbo… resend it if it’s been more than a few weeks!

And as you get more experienced:

Speak at WordCamps and other events

Once you’ve gained enough kudos in the WP community, you’ll likely be asked to talk at a WordCamp event. And if you haven’t, and you think you could bring something special to the event, go ahead and ask if they need any more speakers! This will raise your profile further, introduce you to really cool people, and provide you with a bunch of business leads. BarCamps, social media gatherings, and other such events are also worth attending. The point isn’t to get up there and give a business pitch. In fact, your life might be in danger if you pull that stunt at a BarCamp. The point is to impart knowledge, connect with people, while letting your skills expose themselves naturally. And pitch away when you’re chatting up potential leads between sessions.

Charge according to your skill set and experience

Several years ago, I had the quasi-embarrassing surprise of being given a voluntary 75% per-hour raise by a client. I think they were afraid that my skills had outpaced my rate, and that I was going to get wooed away by a new client at a higher rate. Don’t make the mistake of charging too little. In fact, publish higher rates than you actually think you’re worth, and allow people to haggle you down (a little). And every time you get booked up and have to turn away business, raise your rate. If you’re in that much demand, you’re not charging enough.

Find a niche

But not WordPress security. That’s mine. :-)

A WordPress development niche is a niche within a niche. And that means you can charge more for your more specialized skills. Examples: migrating data to WordPress. Feed kung-fu. Re-implementing a design from another system. Custom write-panel plugins. Sidebar widgets.

Written by Mark Jaquith

June 6, 2009 at 11:57 pm

Posted in wordpress

GigaOM Pro launches on WordPress and BuddyPress

with 44 comments

2009 is the year of BuddyPress. It’s also the year where online content providers have to figure out how to make money outside of the flailing “get a lot of views, sell ads” model. For the past couple of months, I’ve been working on a project that tackles both of those things, and I’m really proud to present it to the world:

GigaOM Pro is a WordPress/BuddyPress-powered premium research membership site, focused on four initial verticals: Mobile, Green IT, Infrastructure, and the Connected Consumer. A network of independent analysts provide in-depth research papers and research notes, which subscribers can view on the site or download as PDF documents. GigaOM Network contributors provide “long view” posts — topic-focused long form posts. And each of the topic verticals has a curator who provides weekly updates on the topic, as well as a constant stream of curated links to relevant external stories. Subscribers can access all the content, comment on the content, have a profile on the site, and send messages to Analysts, Contributors, Curators, or other subscribers using the BuddyPress messaging system.

Here’s what it looks like:

GigaOM Pro home page

GigaOM Pro home page

The content is incredibly compelling. I’ve been especially impressed with the quality of the Long View posts. More than once when developing the site I would get distracted by one of these pieces and have to read the whole thing. The GigaOM writing staff and the analyst network are very talented people, and I think that $79 a year is a steal for this calibre of hyper-focused content and this sort of access to industry analysts.

From a technical perspective, it was interesting to create a site with such distinct content types. The Write screen for Curated Links looks nothing like the Write screen for Weekly Updates, or Research Briefs. The system makes heavy use of the category system, and custom WP_Query objects and loops. category__not_in, category__and and post__not_in are very powerful tools for getting the correct entries from the system.

Naturally, there are no core WordPress hacks — everything is implemented through plugins and the custom theme!

Let me know what you think. And don’t subscribe — I put in a lowball prediction in the internal betting pool for how many subscribers there are in the first week, and I think I’m going to lose. :-)

Written by Mark Jaquith

May 28, 2009 at 6:58 pm

State of the Word – WordCamp Mid-Atlantic

with 25 comments

Here are my slides from the State of the Word keynote at WordCamp Mid-Atlantic:

Written by Mark Jaquith

May 17, 2009 at 6:30 am

Posted in wordpress

Tagged with , , ,

Force CSS changes to “go live” immediately

with 60 comments

If you update your WordPress theme’s style.css, you may have noticed that you have to “force-reload” your site in your browser to see the changes. This is because your browser keeps a copy of the CSS cached on your hard drive. Depending on how your server is set up, it may not check for a new version of the stylesheet for a couple hours, or longer! And even if you force-reload to see the changes, visitors who have previously accessed your site may still get the old CSS. One way to solve this is to “version” your CSS file, by adding ?v=123 to the URL in the <link /> to your stylesheet. This is rather a pain to have to do by hand every time, so here is a much better way:

<link rel="stylesheet" href="<?php bloginfo('stylesheet_url'); echo '?' . filemtime( get_stylesheet_directory() . '/style.css'); ?>" type="text/css" media="screen, projection" />

This automatically updates the ?12345678 ending part every time you modify the file. Boom. Now everyone instantly sees your changes.

Written by Mark Jaquith

May 4, 2009 at 5:47 pm

Posted in wordpress

Typographica relaunches on WordPress

with 15 comments

Typographica, the excellent blog for typographical nerds, has just relaunched on WordPress with a great new design by Chris Hamamoto. Asked why they switched from Movable Type to WordPress, Stephen Coles replied:

For me, it seemed an obvious switch given WordPress’ wide adoption in recent years. We’ve often had trouble getting assistance with MT, whether it’s documentation or expert advice. Because WordPress is so common, the help resources and useful plugins are simply much more accessible.

WordPress’ killer features are its community and its marketplace: thousands of free plugins, thousands of free themes, and hundreds of agencies and freelancers providing every possible WordPress development and support service you can imagine.

Written by Mark Jaquith

April 24, 2009 at 3:07 am

Beta testers needed for Subscribe to Comments

with 21 comments

I have a new version of Subscribe to Comments that will be coming out soon. The storage system for the subscriptions is changing (or rather, being consolidated into one method, instead of being spread into two). The good news is that this new version has zero database schema changes from WordPress core. It also adds support for double opt-in subscriptions for compatibility with German law (and possibly others). Before I release this version, I’d like some other people to test it, especially to make sure that the transition of subscription storage method works smoothly.

What I need are two or three people who meet the following criteria:

  1. Current running WordPress 2.7 or 2.7.1
  2. Currently running Subscribe to Comments 2.1.2
  3. Have a large number of comment subscriptions (at least 500)
  4. Are able to make a SQL backup of their comments table prior to testing, and restore it in the event that something goes wrong

If you meet those criteria, send an e-mail to mark.stcbeta@txfx.net and I’ll get you hooked up.

Written by Mark Jaquith

April 11, 2009 at 2:10 am

WordPress iPhone Skin

with 34 comments

Check out the awesome WordPress skin that my iPhone is rocking.

 

WordPress skin for the iPhone 3G

WordPress skin for the iPhone 3G

It’s my understanding that these will eventually be available for sale in the WordPress Shop.

Written by Mark Jaquith

March 26, 2009 at 12:40 am

Posted in wordpress

Tagged with , ,

Heading to SXSW, WordPress consulting availability in mid-May

with 5 comments

Tomorrow I’m heading off to Austin, TX for the South by Southwest Interactive Festival. If you’re going to be there, and you’re a WordPress fan, make sure you say hi and let me know what cool uses you’ve found for WordPress! The best way to find out where I am or to get in contact with me is to follow me on Twitter. Ping me in an @message if you’d like to chat.

Also, if you have need of a WordPress guru, I’m back on the market! My contract with b5media has moved to a part-time arrangement, so if you’re looking for someone to figure out how WordPress and your company or product fit together, drop me a note or track me down while I’m in Austin. I have a really exciting secret project occupying my time until mid-May, but if you can wait a few months to start your project, we can start that conversation now.

Written by Mark Jaquith

March 12, 2009 at 3:27 pm

Posted in wordpress

Tagged with , , ,

BarCamp/WordCamp Miami

with 10 comments

BarCamp Miami

I’ll be in Miami on Sunday, February 22nd for BarCamp/WordCamp Miami. If you’re in the area or are in town for the Future of Web Apps conference, you should stop by!

What should I talk about?

Update: There has been a venue change for this event, so if you were planning on going, make sure you take note of the new location!

Written by Mark Jaquith

February 17, 2009 at 4:26 am

Posted in wordpress

Tagged with , , ,