Tag Archives: wordpress

WordPress multisite in subfolder

If you install wordpress in a subfolder like /home/example/public_html/wordpress instead of the main DocumentRoot ( usually /home/example.com/public_html ) you will not be able to enable multisite functionality but with a few small changes to wordpress code you can make it work.

My goal was to have the main site ( example.com ) with multisite, host blogs on subdomains like dom1.example.com and then use domain mapping so I could map a domain like dom1.com to dom1.example.com.

Here are the steps I took:

  1. Extract wordpress-3.1.3.zip in /home/example.com/public_html/wordpress, go to went to http://example.com/wordpress and install, then login as admin to http://example.com/wordpress/wp-admin
  2. In wp-admin -> Settings both WordPress address (URL) and Site address (URL) were set to http://example.com/wordpress, change Site address (URL) to http://example.com
  3. copy index.php and .htaccess from /home/example.com/public_html/wordpress to /home/example.com/public_html/
  4. open /home/example.com/public_html/index.php in an editor and changed the line:
    require('./wp-blog-header.php'); to require('./wordpress/wp-blog-header.php');
    At this point you have a working wordpress installed in a subfolder accessible at http://example.com
  5. Open wp-config.php and insert the following lines at the top ( can be right after the first line )
    define('WP_ALLOW_MULTISITE', true);
  6. Open the file wordpress/wp-admin/network.php in a text editor, look for the line: "function network_step1" and a few lines bellow there should be a line:
    1. if (get_option( 'siteurl' ) != get_option( 'home' ) ) {

    , replace it with

    1. if ( 0 && get_option( 'siteurl' ) != get_option( 'home' ) ) {
  7. Now go to http://example.com/wordpress/wp-admin/network.php and create your network.
  8. After you create the network, WordPress will ask you to add a few lines to wp-config.php but you'll have to modify them a bit. Here's what I added:
    1. define( 'MULTISITE', true );
    2. define( 'SUBDOMAIN_INSTALL', true ); // default was false
    3. $base = '/'; // default was /wordpress/
    4. define( 'DOMAIN_CURRENT_SITE', 'example.com' );
    5. define( 'PATH_CURRENT_SITE', '/wordpress' );
    6. define( 'SITE_ID_CURRENT_SITE', 1 );
    7. define( 'BLOG_ID_CURRENT_SITE', 1 );

    By default SUBDOMAIN_INSTALL was set to false but you want subdomains, and $base was set to "/wordpress" but this needs to be "/"

    Don't forget to also add the required lines to .htaccess ( the one in the wordpress/ directory )

  9. After the network was created, wordpress messed up a bit with the permalink settings for the main domain. Before, the permalink structure was set to: /%year%/%monthnum%/%day%/%postname%/ and wordpress changed it to /blog/%year%/%monthnum%/%day%/%postname%/.
    But after I added the above lines to wp-config.php I was able to change the permalink structure back to what it was from Settings->Permalinks
  10. Adding domains

    Go to Network admin ( http://example.com/wordpress/wp-admin/network/ ) -> Sites -> Add new . I added
    an example domain dom1.example.com. This is what I'll use as an example from now on.

    After I added the domain I went to Sites , clicked the Edit link bellow the domain and changed Path from / to /wordpress ( with the option "Update siteurl and home as well" checked ) then go to the Settings tab and change the Home to http://dom1.example.com/
    At this point you have a working wordpress installed in a subfolder with multisite configured with subdomains.

  11. Install the domain mapping plugin with my changes
    • Download the zip file from : http://patchlog.com/wordpress/wpmu-domain-mapping-in-subfolder-install/
    • Extract in wp-content/plugins
      1. mkdir wp-content/mu-plugins
      2. mv wp-content/plugins/wordpress-mu-domain-mapping/domain_mapping.php wp-content/mu-plugins
      3. cp wp-content/plugins/wordpress-mu-domain-mapping/sunrise.php wp-content
    • edit wp-config.php and add the line:

    1. define( 'SUNRISE', 'on' );

    right after the first line

  12. got to Network Admin -> Tools -> Domain Mapping to configure the plugin and add the mappings
  13. Come back and let me know how it worked in the comments

WpMU Domain mapping in subfolder install

Here's a solution to run a wordpress multisite installation with domain mapping even if you didn't install wordpress in the DocumentRoot of your site.

If you want to map domains to subdomains in your wordpress install for example womsend.ro to ro.womsend.com you would use the wordpress-mu-domain-mapping plugin but this only works if wordpress is installed dirrectly in the web site's document root not in a subdirectory.

I like to have wordpress installed in a subdirectory because it keeps things organized especially if I have other things installed on your site.

So here is a patch to the wordpress domain mapping plugin that allows it to work with the subdirectory install. Download the original plugin then apply the patch (this patch is for the 0.5.4 version of the plugin):
Wordpress mu domain mapping subdir install-0.2 (5.27 kB)

Or just download the plugin already patched for convenience:
Wordpress mu domain mapping plugin patched for subdir install -0.5.4.1 (22.61 kB)

After adding a new site you have to go to Network Admin -> Sites, select the site and edit some of it's configuration values ( wordpress default values will not work ):

1) In site Info Tab, the Path is set to "/" . You have to add the subdirectory to it. For example if your site's document root is /home/site/public_html and wordpress is installed in /home/site/public_html/wordpress then the Path should be set to /wordpress
2) After saving the changes at #1, in the site Settings tab , Siteurl should already be set to http://{SubDomain}{Path} where {Path} is the path set at #1, but if it's not then set it.
3) The changes at #1 also modified ( in wp 3.1.3 anyway ) the "Home" value in the Settings tab , adding the Path to it but this has to be clean of the path so you have to change it back to http://{SubDomain}/

That's it, let me know how it works in the comments.

Hidden Affiliate Links 1.0

Finally after a long time, The Hidden Affiliate Links plugin for WordPress 3.0.1 is here.

The previous version stopped working a long time ago when wordpress 2.5 was released ( yes it's really that long ago ).

I tested the current version on WordPress 3.0.1. It might work on older versions but I don't plan to support them.

The download, install and usage instructions are on the plugin's page.

I tried to host this plugin on the official wordpress plugins repository so you could see update notifications right in wordpres admin but apparently someone there doesn't like the fact that this plugin hides links so it was not accepted.

I think this is wrong because there are other plugins there that can somehow hide links ( like the redirection plugin ) and even without a plugin if someone wants to hide a link they can still do it easily by using any url shortner.

Anyway the idea is if you want to be notified about updates make sure you subscribe to my RSS feed.

Feel free to ask any questions about this plugin in the comments.

Simple Hotlink protection for SEO profits

This post is not about protecting images against hotlinking, it's about protecting your downloads against hotlinking.

Problem

If you've been reading this blog you might have noticed I published some wordpress plugins, patches and an xml sitemap module for pligg. Sometimes other people write posts about my patches but instead of linking to my posts they link directly to the download. This creates a series of problems: people might miss important information about the download, page rank is uselessly transferred to a zip, tar.gz, or .patch file, and you're basically serving content for other people's posts while they rip all the benefits.

Solution

So here's an easy way to avoid it. Well you can't really avoid it but you can benefit from it. All you have to do is set up a .htaccess file in your wp-content/upload directory ( that's where downloads are storred by default, feel free to change the location if you're using something else.

This .htaccess file will check the referer of every request on any file in that folder and if the referer doesn't match your domain it will redirect the visitor the search page on your blog with the search term set to the name of the file they wanted to download. most of the time this search will show as the first result the post where you published.

Here's how the file looks on my blog:

RewriteEngine On
RewriteBase /wp-content/uploads/
RewriteCond %{HTTP_REFERER} !(www\.)?patchlog.com [NC]
RewriteCond %{HTTP_REFERER} !^$
RewriteRule ([^\/]+)$ http://patchlog.com/index.php?s=$1 [R=permanent,L]

Pretty simple huh?
What about the SEO profits?
As you can see the last rule redirects using a permanent redirect and this means google will transfer page rank to the search page.

Other solutions?

This method is good because it's really easy to implement, but I would like a method that would redirect the visitor directly to the post page instead of the search page.  I'm hoping the wordpress download monitor plugin that I'm using will at some point implement an advanced hotlink protection method but until then or until I find time to do it myself this is good enough.

Manual Wordpess Version Check

When a new wordpress version is released you'll probably find out about it sooner then it will be available for automatic installation in your wordpress admin.

This is because wordpress checks for new versions twice a day,but the check is scheduled based on the time when you installed wordpress so unless you're lucky you'll have to wait for up to 12 hours before the update shows up in your wordpress admin and use it.

This gave me the idea that it would be nice if you could check manually as soon as you find out about the upgrade, so I created this plugin that just gives you a button that you click and it will check to see if there's an update available right away. If it finds on it shows you the upgrade link.

Download: WP Version Check-0.1 (95.2 KB)

To check for an update go to wordpress admin -> Tools -> Version Check

OpenID server on php 5.3

You want to turn your blog into an OpenID server so you can login to sites accepting OpenID with your own OpenID url.One nice advantage of this is that if you're already logged into your blog you don't have to provide a username and password anymore.

The Problem

You install the OpenID plugin, configure it as a server, but you run php 5.3 and the server part of this plugin doesn't work with PHP 5.3.

The Solution

Download my patch ( for OpenId 3.3.2 plugin ) :OpenID Server php 5.3 patch-0.1 (907 bytes)

Copy to wp-content/plugins and run:

patch < openid-server-php.5.3.diff

For the lazy ones here's a version of the OpenID plugin that's already patched: OpenID Server php 5.3 Patched Plugin-3.3.2 - 0.1 (402.61 KB)

Just install it instead of the original plugin.

You want to turn your blog into an OpenID server so you can login to sites accepting OpenID with your own OpenID url.One nice advantage of this is that if you're already logged into your blog you don't have to provide a username and password anymore.

Follow Self Pings

The Problem

Wordpres creates all links to comment author's site or pingbacks/trackbacks with "nofollow external" . This includes links to your own blog. Apparently this is bad for your pagerank according to this post:Pinging Your Own Blog Posts? Good or Bad?

The Solution

On that article mentioned above, the author suggested that you can use a plugin that would make wordpress stop creating pingback links to your own blog. I didn't like that idea so here's mine: a plugin that will make wordpres NOT add "external nofollow" to the pings to your own blog.

The plugin doesn't require any configuration, just download, install , activate and forget about it.

Download

UPDATE: The plugin is now hosted in wordpress plugins directory. That means you can install it dirrectly from  your wordpress admin or go to it's page to download it: Follow Self Pings Plugin

The first version of the plugin had a small bug that prevented it from working on blogs that were installed in one directory and had the home page pointing to something else. This bug is fixed in version 0.2 . You should be able to  update it from the plugin admin.

Faster wordpress page admin

In a recent post about wordpress I explained how you can create a lot of pages really fast.  If that went well and you inserted a few thousand pages in your wordpress blog  the page admin became useless. Displaying the list of pages would take 3 minutes for 7000 pages on my test server.

It seems this is not a new problem and there is a bug created in 2007 about it. Although it seems like there was a patch to fix this, the problem still exists in the 2.8.4 version.

Why is this so slow ?

Short story: because wordpress is trying to display and sort pages hierarchically .

At first I thought the problem was caused by the sql queries that fetched all the pages ( even though it doesn't display all of them on a page ) but that was not the case.

After profiling the code with xdebug and Kcachegrind I found there were a few parts of the code that were taking the longest time to complete.

The main problem is that wordpress is trying to find the children for all the pages in an inefficient way. There is this function get_page_children in wp-includes/post.php  which was taking about 2 thirds of the total time to complete ( ~ 2 minutes on my example  ).

The Solution

I rewrote that function to make it a lot more efficient. In my case it reduced the time from 2 minute to 1-2 seconds but on other page hierarchy it might take more, the worst case being when every page is the parent of another page.  The diff is here : Fast page_get_children-0.1 (1.05 KB)

The second problem is that wordpress updates the page cache every time you list pages. This was taking almost 1 minute to complete. I'm not sure if it's the right thing to just remove that call to update_page_cache in wp-includes/post.php get_pages , but doing that made the page admin load in about 15 seconds.

Now this might still be annoying but it's way better then 3 minutes. Hopefully at least the new get_page_children function will b included in the next wordpress release... maybe you can help promote this ticket by giving it a positive vote although I'm not sure if those votes actually have any influence.

Ask me questions

Have a question about unix, linux, freebsd.  Or maybe you want some advice about configuring apache, mysql,an email server like exim, qmail, postfix, a proxy server like squid cache or antinat, dns or anything else similar. Want some help with php programming or maybe you want to create a wordpress plugin?

Feel free to ask and I'll do my best to answer it on this blog. I will publish a new blog post for each question and my answer.

You can use the contact form or ( if your question is short enough ) you can send it to me over twitter

You can follow me on twitter or subscribe to my RSS feeds if you want to be notified when I post the answer to your question.

WP-Twitter-ID Social Profiles Integration

A few days ago I wrote a post about a wordpress plugin that will add a twitter id field to the comments form and I was reporint two problems with it. One was solved in that post and for the second one I'm going to show you a solution in this post.

The Problem

The second problem was that the twitter id field was show assigned to a comment when a registered user was commenting.

Basically I needed a way to specify the twitter id of a registered user in the profile and then just make the WP-twitip-id plugin use that value form the profile. I could have done this by implementing the necessary code to show the field on the profile page and save it's value when the profile was saved but I was lazy and I wanted a quicker solution.

The Quick Solution

The quick solution was to install the Social Profiles plugin, set my twitter id in my profile and then do a simple modification to wp-twitip-id.

To make the modification just open wp-twitip-id.php in any editor, look for "function addtwitterfieldmeta($comment_data){" and right after that line insert the following code:

  1. if(!empty($_POST['atf_twitter_id'])){
  2. $twitter=$_POST['atf_twitter_id'];
  3. }else{
  4. $current_user = wp_get_current_user();
  5. $user_id = $current_user->ID;
  6. $twitter=get_usermeta($user_id,'cyc2_twitter');
  7. }

That's it. Simple don't you think ? Now next time you post a comment as a registered user you should see your twitter id in the comment header.

Download

Here's the zip file with all modifications including the one in the previous post.

WP-Twitip-ID-0.9.2 (13.3 KB)