I just changed the table prefix from "wp_" to "wp_en_us_" to support multiple installs in the same database, one for each locale. This seemed pretty straightforward - just rename the table names and change the table prefix in wp-config.php, right?
Wrong.
The WP code is littered with references to $table_prefix - including columns in the "usermeta" and "options" table. Key columns such as "wp_capabilities" in the "options" table need to be renamed appropriately, or your user roles are totally broken. In "usermeta" you need to make sure the "wp_user_level" and "wp_capabilities" meta_keys are updated too.
Sadly, after spending a couple hours var_dump() and exit()'ing throughout the code I realized the issue. I am not exactly sure the prefix of some of these keys needs to be aligned with the $table_prefix - maybe WPMU uses that or something. But anyway, what an annoying headache.
I am not sure but I think -all- "wp_" keys might need this same treatment. I've only really cared about the user roles and such since I had a lot of users trying to figure out why they can't post anymore. At least that's fixed.
Note: I don't know if this is clearly documented anywhere. If it is, I should be embarrased. However, I still want to voice a complaint that this isn't very straightforward. Maybe put a comment in wp-config.php?
I don't know how or when, but I wound up getting indexed with index.php in some of my URLs.
For some reason, WordPress hasn't decided that they should parse and remove that. So for the interim, I've decided to finally throw in a couple quick lines of code to do the trick. Throw it in any plugin you want or make a standalone file, it works fine with my 2.6.1 so far.
add_action('init', 'chop_index');
function chop_index() {
if(preg_match('/index\.php$/', $_SERVER['REQUEST_URI'])) {
$url = preg_replace('/index\.php$/', '/', $_SERVER['REQUEST_URI']);
$url = preg_replace('/\/\/$/', '/', $url);
header("Location: http://".$_SERVER['HTTP_HOST'].$url, true, 301); exit();
}
}
Note: this has been outdated now. I have an updated post with the latest and Igor-approved method here.
When I was switching over to nginx, I found a handful of random and overkill config examples to make it work. I thought I had found the simplest solution already, but Igor (the creator of nginx) actually gave me an even "better" solution in nginx.
This is assuming WordPress is physically installed in /wordpress, and pages are served up using friendly URLs, /2008/02/03/post-title/ - just like this site. All the rewrites are off the root. I assume you've already got PHP setup to parse properly and you have a working server {} block. I'll post that info too if people really need it.
1st example (seems like overkill, can't figure out a reason why people are splitting up the rewrite rules - I guess because they assume "wp-anything" is all static?):
if (!-e $request_filename) {
rewrite ^([_0-9a-zA-Z-]+)?(/wp-.*) $2 break;
rewrite ^([_0-9a-zA-Z-]+)?(/.*\.php)$ $2 last;
rewrite ^ /index.php last;
}
2nd example (this was as good as I thought it could be, but I was wrong):
if (!-e $request_filename) {
rewrite ^(.+)$ /wordpress/index.php?q=$1 last;
}
3rd example (this is the best, according to Igor):
error_page 404 = /wordpress/index.php?q=$uri;
(Ref: http://article.gmane.org/gmane.comp.web.nginx.english/4739)
I've had two requests now for MySQLi updates, so here ya go. It's pretty simple to do it yourself - just look for any mysql_ string, replace it to mysqli_ (where applicable) and in some instances, change the order of the parameters.
Below is the version of wp-includes/wp-db.php for production WP 2.3.3
Below is a version that works against the latest in SVN trunk (right now revision 7152) using the new db.php override feature (apparently still not in 2.3.x)
Let me know if there are any issues, but in my quick little sandbox I made it worked fine...
It is almost perfect - just tar xvfz latest.tar.gz and let it overwrite the files in the wordpress/ dir... but life isn't easy like that.
A bunch of files have been deprecated from various releases and just sit around getting stale. Currently the installation instructions are to just "remove all files" in various places. I would rather just get a list of files that are safe to remove, and be able to blindly copy the archive using tar (or remotely using FTP, etc.)
That shouldn't be too hard.
Right now I have my WP installs for work and home in Subversion, and I can't just move the files because the SVN metadata and directories get lost. I'd prefer to just get a list and I can manually just "svn del" the files myself. So please, for future WP releases, would someone publish the list of files so I don't have to do all this manual work each time? How about a quick and dirty cheat sheet like so:
List of files deprecated by this release:
- foo.php
- bar.php
Database upgrade required: Yes/No
Functions changed or deprecated:
- wp_insert_post() now does this instead of that...
- etc...
This might also make it easy for [us] plugin authors to look at the function deprecation list and easily know if something we're doing could be in trouble ![]()
It took me a bit to find out why jQuery (now bundled with WordPress) was not working as I expected inside of the WP admin area. The script was being called, but my code like $("#foo") was not working. I really had no clue where to begin, since it still has all those old JS libraries/frameworks being called as well. It was due to Prototype being packaged with it and conflicting with the "$" shortcut.
Long story short, jQuery already planned for library conflicts and has a quick solution. The no-conflict mode allows you to define your own shortcut, and of course it works like a charm.
It's easy to do - just put this line in your code somewhere:
var J = jQuery.noConflict();
Now $("#foo") will be J("#foo") and it will not conflict with any other libraries that may be installed. I hope WP gets rid of all the other stuff and goes with pure jQuery and plugins soon enough though ![]()
I have noticed (and also reported this on the WP site) that when a user clicks "Publish" it does not check for empty post titles or empty post bodies. I believe this is a flaw in design. The code is there to check, but it doesn't work right; it allows for empty post bodies or titles for drafts (which is okay, they might not have a title yet) but it should stop the user from being allowed to publish an empty post.
Below is the code I came up with after messing around for hours... it relies on the bundled jQuery in the latest WP 2.x versions. It does client-side checks to alert the user to fix the issue, but there is no graceful way (at least that I could find) to handle this if the user does not have JavaScript or anything enabled. If the server gets an empty title or body, it will empty all the fields out, essentially forcing the post to fail. The user *will* lose their work then (unless their back button works nicely.)
The typical user will typically have JS enabled, and they shouldn't be publishing without a title. However, I am dealing with some inexperienced bloggers - so I want to make sure I have all the bases covered. Once again, the reason this is so ugly is due to the fact that I do not modify the core WP code; everything I do is in plugin fashion (although I did suggest a quick fix in the WP core code in my forum post.)
Links to my forum post and the bug submission:
Here's the code:
function empty_filter($text) {
return '';
}# if any field is empty, forcibly empty the fields so that it will fail post publishing
function check_empty_title() {
if(isset($_POST['publish']) && $_POST['publish'] == "Publish") {
if(empty($_POST['post_title']) || empty($_POST['content'])) {
add_filter('content_save_pre', 'empty_filter');
add_filter('excerpt_save_pre', 'empty_filter');
add_filter('title_save_pre', 'empty_filter');
}
}
}
add_action("load-post.php", 'check_empty_title', 1);function check_empty_clientside() {
echo <<<EOF
<script language="javascript" type="text/javascript">
var wpJ = jQuery.noConflict();
wpJ(document).ready(function() {
wpJ("#post").submit(function(){
if(wpJ("#title").val() == '') {
alert('You must put something in the post title!');
return false;
} else {
if(tinyMCE.getContent() == '') {
alert('You must put something in the post body!');
return false;
}
}
});
});
</script>
EOF;
}add_action('admin_head', 'check_empty_clientside', 1);
I've had the opportunity to work with WP plugin creation quite a bit at work. We've been able to enforce a strict policy on our WP blog of not allowing *any* core WP code to be modified. The main reason for this is that it will make it much easier to upgrade and not break functionality later on.
Due to that, I've wound up creating or hacking up a bunch of custom plugins for work. One includes a complete authentication system override. Basically it traps all login, logout and registration requests and pushes them to custom URLs, and I trap all requests and process user information from cookies our external authentication system has defined. Then I take that information and force-feed it into the WP system, essentually telling it to emulate who I want it to.
That's not a very general-purpose one for any WP installations outside of my company though. However, I have created one that so far seems to be quite useful, and depending on responses, I may package/fix up more.
As of right now, I wind up customizing almost every plugin I use. Currently, all but the Akismet one is either completely written by me, or was taken from another one and hacked up with extra features.
My current plugin list includes:
It seems like I use a lot more. I guess I felt cool having a handful of custom plugins, but I really only run a couple on my personal site for now. As I mess around with more, I'll be sure to post.
One thing I would like to see is the database functions put into the pluggable functions. Then I could create a MySQLi plugin that could override the core MySQL calls. That'd be a pretty easy way to allow for custom backends; in the meantime, it looks like I am stuck putting in a wp-content/db.php file (I believe that is the way to do it.)
While we're on the subject of plugins, I think I should be clear here. A "plugin" should not require the stock WP code to be altered. That is a patch or a hack. A plugin is something that can be plugged in without any modification of the core code.
I don't know why this wasn't discovered (or a better action put in by the WP folks to begin with that could be disabled) but I was able to find a way to disable the feeds from loading on the WordPress admin dashboard without any need for customized index.php files (which would need to be updated/re-uploaded every time WP is updated.)
I'm not sure why this isn't just a stock WP configuration option. It seems enough people have looked for ways around it. My biggest issue was that it requires connectivity directly with each RSS feed, which does not work very well behind our firewall at work. I'll be damned if I hack up some proxy-capable solution too for the feeds that we don't really even look at.
I knew that there had to be a way to mess with the actions being called to disable them from loading the Javascript, or make the fetch_rss() calls return nothing, or make the index-extras.php script return nothing... the easiest and apparently effective way was making a simple action trigger and finding the right order in which it was effective.
In the end, this is all the code that was required:
function remove_dashboard_feeds() {
remove_action('admin_head', 'index_js');
}add_action('admin_head', 'remove_dashboard_feeds', 1);
To make a long story short, I give you the "Remove Dashboard Feeds" plugin, located here. Just download, remove the .txt extension, throw it in the plugin directory and activate it. Simple enough. Works on WP 2.2, and probably 2.1. Not sure about earlier versions, but nobody should be running those anyway (keep up with the times as much as you can! Stay secure and optimized!)
Yet another patch (actually the same one, but copied for version compliance.)
Patch file: wordpress-2.0.7-mysqli.patch
Apply with: "patch -p0 < wordpress-2.0.7-mysqli.patch" in the WordPress install directory.