WordPress: Add footer text to feed posts

Here’s a small code snippet for adding text to the bottom of each post in your rss feed. This will not affect the post content shown on your site.

The below should be added to your themes function.php file.

/********************************************************************************
* Add Footer to RSS feed
*/

function mdr_postrss($content) {
    if(is_feed()){
        $site_name = get_bloginfo_rss('name');
        $post_title = get_the_title_rss();
        $home_url = home_url('/');
        $post_url = post_permalink();
        $content = $content.'<a href="'.$post_url.'">'.$post_title.'</a> is a post from: 
<a href="'.$home_url.'">'.$site_name.'</a> which is not allowed to be copied on other sites.';
    }
    return $content;
}
add_filter('the_excerpt_rss', 'mdr_postrss');
add_filter('the_content', 'mdr_postrss');

Or may be found on github.

WordPress Correct File Permissions

To lock down the permissions on your WordPress install, from inside the WordPress site directory, run the below commands.

chown -R root:root .
chown -R nginx:nginx wp-content wp-admin/update.php wp-admin/update-core.php 
wp-admin/network/update.php wp-admin/network/update-core.php

Note, the above command assumes you are running under Nginx, if you are under Apache, please run the 2nd command replacing nginx with apache

The above command will change all the files in your WordPress root to the ROOT user, then change only the needed files back to user your web server is running as. This will allow you to update themes & plugins, and will also let you upload images, but you will not be able to update WordPress without changing the owner/group back to nginx on your WordPress root.

Installing WordPress on Nginx

I, like most people, started out by using Apache and really didn’t see anything wrong with it.  It’s relatively easy to setup, it’s used by most sites so support is a snap and a default and it’s already installed on most distributions. The thing is, it’s slow, the easy of use is paid for by speed.

So this is where Nginx comes in.  Nginx is not the easiest software to setup.  It requires you to tell it what different file types you will be using and how to handle them.  It requires you to tell it where scripts live and where static files live.  It also requires you to use an external php server, such as FastCGI.

PHP-FPM Setup

Nginx does not provide FastCGI for you (FastCGI is what your web server uses to interact with WordPress’s PHP code), so you’ve got to have a way to spawn your own FastCGI processes.

My preferred method is using of running FastCGI is with php-fpm.  Since I’m using Fedora, and there is a yum packet already built for php-fpm, it’s quick and easy to install.

Installing php-fpm is pretty straightforward:

yum install php-fpm

After installing php-fpm you have to start it. The rpm for php-fpm installs the service script for you, you only need to enable starting at boot, and start the process.

chkconfig php-fpm on
service php-fpm start

Nginx

The next part is to install Nginx on your server.  This is as straightforward as installing php-fpm on Fedora, when using yum.

yum install nginx

Once Nginx is installed, you need to set it up to server your site.

Configuring Nginx for WordPress

So we now have the needed software installed, next we need to set it all up. Below is the config for a standard, simple WordPress site named example.com.
nginx.conf:

http {
    include       /etc/nginx/mime.types;
    default_type  application/octet-stream;

    log_format  main  '$remote_addr - $remote_user [$time_local] $http_host "$request" '
                      '$status $body_bytes_sent "$http_referer" '
                      '"$http_user_agent" "$http_x_forwarded_for"';

    access_log  /var/log/nginx/access.log  main;
    sendfile        on;
    #tcp_nopush     on;
    rewrite_log     on;
    keepalive_timeout  5;
    index              index.php index.html index.htm;

    # Upstream to abstract backend connection(s) for PHP.
    upstream php {
        server unix:/var/run/php-fpm.socket;
    }

    server {
        listen 80;
        server_name example.com;
        server_name www.example.com;
        root /var/www/example.com;

        if ($http_host != "example.com") {
                rewrite ^ http://example.com$request_uri permanent;
        }

        include wordpress.conf;
    }
}

wordpress.conf:

# WordPress single blog rules.
# Designed to be included in any server {} block.

# Deny all attempts to access hidden files such as .htaccess, .htpasswd, .DS_Store (Mac).
location ~ /. {
        deny all;
        access_log off;
        log_not_found off;
}

# Deny access to any files with a .php extension in the uploads directory
location ~* ^/wp-content/uploads/.*.php$ {
        deny all;
        access_log off;
        log_not_found off;
}

# Deny access to any files with a .php extension in the uploads directory for multisite
location ~* /files/(.*).php$ {
        deny all;
        access_log off;
        log_not_found off;
}

# This order might seem weird - this is attempted to match last if rules below fail.
# http://wiki.nginx.org/HttpCoreModule
location / {
        try_files $uri $uri/ /index.php?$args;
}

# Add trailing slash to */wp-admin requests.
rewrite /wp-admin$ $scheme://$host$uri/ permanent;

# Directives to send expires headers and turn off 404 error logging.
location ~* .(js|css|png|jpg|jpeg|gif|ico|ttf)$ {
        expires 180d;
        log_not_found off;
}

# Pass all .php files onto a php-fpm/php-fcgi server.
location ~ .php$ {
        # Zero-day exploit defense.
        # http://forum.nginx.org/read.php?2,88845,page=3
        # Won't work properly (404 error) if the file is not stored on this server, which is entirely possible with php-fpm/php-fcgi.
        # Comment the 'try_files' line out if you set up php-fpm/php-fcgi on another machine.  And then cross your fingers that you won't get hacked.
        try_files $uri =404;

        fastcgi_split_path_info ^(.+.php)(/.+)$;
        #NOTE: You should have "cgi.fix_pathinfo = 0;" in php.ini

        include fastcgi_params;
        fastcgi_index index.php;
        fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
#       fastcgi_intercept_errors on;
        fastcgi_pass php;
}

Compressing PNG file for the web

When using images on the web, it’s impotent to use the smallest file you can for your needs. This doesn’t mean you should use a image that is smaller then the size you wish to display it at, but to optimize it for the web and not send more then is needed.

With this goal, here is a quick way of optimizing all PNG files in a set of directories using optipng.

for a in `find /var/www/wordpress/ |egrep '*.png$'`
do
    /usr/bin/optipng $a
done

Don’t worry if you already have some images that are already optimized, optipng will just skip them.

Custom WordPress Cron Intervals

Here’s how to have WordPress code execute on a different schedule than the default intervals of hourly, twicedaily, and daily. This specific example is for weekly execution.

<?php

// Add a new interval of a week
// See http://codex.wordpress.org/Plugin_API/Filter_Reference/cron_schedules
add_filter( 'cron_schedules', 'myprefix_add_weekly_cron_schedule' );
function myprefix_add_weekly_cron_schedule( $schedules ) {
	$schedules['weekly'] = array(
		'interval' => 604800, // 1 week in seconds
		'display'  => __( 'Once Weekly' ),
	);

	return $schedules;
}

// Schedule an action if it's not already scheduled
if ( ! wp_next_scheduled( 'myprefix_my_cron_action' ) ) {
	wp_schedule_event( time(), 'weekly', 'myprefix_my_cron_action' );
}

// Hook into that action that'll fire weekly
add_action( 'myprefix_my_cron_action', 'myprefix_function_to_run' );
function myprefix_function_to_run() {
	// Add some code here
}

?>


Taken from Viper007Bond‘s post on How To Create Custom WordPress Cron Intervals.

Configuring WordPress to use Memcached

When using WordPress self hosted software it’s generally a good idea to cache as much as possible.  Object Caching allows you store parts of the pages in memory for quicker retrieval, since the server will not need to look as much up from the SQL database.

Installing the needed parts

To start out, you will need to have memcached installed on your server. If your using Fedora, you may install memcached via Yum as follows.

yum -y install memcached php-pecl-memcached perl-Cache-Memcached

Configuring memcached

After installing memcached you need to configure it. If working in Fedora, and using the Yum install as talked about above, you will need to change the memcached confuration by modifying it’s sysconfig file located at /etc/sysconfig/memcached.

A default configuration may look like this.

PORT="11211"
USER="memcached"
MAXCONN="1024"
CACHESIZE="64"
OPTIONS="-l 127.0.0.1"

If you would like to share this memcached server with other webservers, change the address from 127.0.0.1 to the server’s actual address.

To set memcached to start automatically when the server get’s rebooted, run:

chkconfig memcached on

And of course, don’t for get to start it

service memcached start

Configuring WordPress

After memcached is installed, you need to configure the WordPress side.

Next you should install the Memcached Object Cache plugin, but be careful, this is not a normal plugin.  You should not activate this plugin as you would with a normal plugin, but instead download it as you normally would, but then you need to copy the object-cache.php file to your wp-content folder.

From the root of your WordPress install, run the following:

cp wp-content/plugins/memcached/object-cache.php wp-content/

Now we need to configure WordPress to use the memcached server. Add the following near the end of your wp-config.php file.

global $memcached_servers;
$memcached_servers = array('default' => array('127.0.0.1:11211'));

Note that were using the same server and port (127.0.0.1:11211) as was configured above while we were setting up memcached.

Checking in on memcached

Memcached is one of those things that just sort of runs. There’s not much direct feed back, besides the speed difference on your site.

One quick way is memcache-top. memcache-top will show you the current status of your memcached server.

To install, run the following.

wget http://memcache-top.googlecode.com/files/memcache-top-v0.6
chmod +x memcache-top-v0.6
./memcache-top-v0.6

Running ./memcache-top-v0.6 will assumed the default configuration we used here.