Category Archives: Programming

WordPress Logo

Stay logged in with WordPress on Subdomains

A clients site performs some magic to show different content per subdomain. By default each subdomain asks you to login, which is a bit annoying. It would be convenient if admins of a single WordPress installation could stay logged in when they jump between subdomains.

I found that all we needed to do was set the cookie domain and path in wp-config.php. At first it seemed only COOKIE_DOMAIN and COOKIEPATH would be needed, but it did not behave until COOKIEHASH was also set. You could probably set it to anything you like, I just had a defined variable already.

/**
 * Set cookie properties to allow persistent login across subdomains.
 */
define('MY_DOMAIN', 'thatstevensguy.com');
define('COOKIE_DOMAIN', MY_DOMAIN);
define('COOKIEPATH', '/');
define('COOKIEHASH', md5(MY_DOMAIN) );

This may also work between WordPress installations across subdomains. I haven’t tested this theory. Both installations would require the same login details and this config. It is working with WordPress versions 3.8+.

WordPress Logo

How to Improve FeedWordpress

FeedWordPress is the best free plugin to syndicate posts from WordPress RSS feeds. Syndication is not the best practice, but it suits the needs of a client and their site network.

However, there is some minor issues. There is no built in duplicate post detection. This can create a mess when syndicating multiple feeds that may contain the same posts. Also, a default category is not assigned to posts if there is no matching category on your site. Place the below filter in your themes functions.php file to correct these issues.

/**
 * FeedWordPress - Detect duplicates and prepare the syndicated post.
 *
 * @param array $post
 * @param SyndicatedPost $syndicatedpost
 * @return array|null
 */
add_filter('syndicated_post', function (array $post, SyndicatedPost $syndicatedpost) {

    // --- Duplicate Detection

    if (!$syndicatedpost->fresh_content_is_update()) {
        global $wpdb;

        $duplicate_post = $wpdb->get_row($wpdb->prepare("
            SELECT ID FROM $wpdb->posts
            WHERE post_status = 'publish' AND post_type = 'post' AND post_title = %s
            AND ( post_date BETWEEN DATE_SUB( %s, INTERVAL 2 HOUR ) AND DATE_ADD( %s, INTERVAL 1 HOUR ) )
            LIMIT 1
        ", [
            $post[ 'post_title' ],
            $post[ 'post_date' ],
            $post[ 'post_date' ]
        ]));

        // Is it a duplicate post?
        if (!empty($duplicate_post)) {
            return null;
        }
    }

    // --- Prepare Syndicated Post

    // Assign the default category when a post has no categories.
    // No idea why FeedWordPress doesn't do this by default.
    if (empty($post[ 'tax_input' ][ 'category' ])) {
        $post[ 'tax_input' ][ 'category' ][] = intval(get_option('default_category'));
    }

    // Syndicated posts will include a 'read more' from the source site at the
    // end of their excerpts. Strip that out.
    $post[ 'post_excerpt' ] = preg_replace("/(&hellip;|&#8230;) <a href=.+<\/a>/", '', $post[ 'post_excerpt' ]);
    $post[ 'post_excerpt' ] = preg_replace("/\\[&hellip;\\]/", '', $post[ 'post_excerpt' ]);
    $post[ 'post_excerpt' ] = trim($post[ 'post_excerpt' ]);

    return $post;
}, 10, 2);

Lastly, we don’t want search engines to index these articles, they aren’t original content on our site. I also make use of Yoast WordPress SEO, we’ll use that to our advantage.

/**
 * Yoast WordPress SEO - Hide Syndicated Posts, and Sign Up form from Search Engines.
 *
 * @return void
 */
add_action('template_redirect', function (): void {
    if (!function_exists('YoastSEO')) {
        return;
    }

    $noindex = false;

    // Don't index Syndicated posts from FeedWordpress
    $is_syndicated = false;
    if (function_exists('is_syndicated')) {
        $is_syndicated = is_syndicated();
    }

    if (is_single() && $is_syndicated) {
        $noindex = true;
    }

    if ($noindex) {
        add_filter('wpseo_robots_array', [ YoastSEO()->helpers->robots, 'set_robots_no_index' ], 10, 2);
    }
});
WordPress Logo

Add a Custom Login Logo to WordPress

Below is all you need to customise the login page of WordPress. Add it to the bottom of your functions.php.

/**
 * Custom Login Logo for WordPress
 */

add_filter( 'login_headerurl', 'tsg_login_headerurl' );
add_filter( 'login_headertext', 'tsg_login_headertext' );
add_filter( 'site_icon_image_sizes', 'tsg_site_icon_image_sizes' );
add_action( 'login_enqueue_scripts', 'tsg_login_enqueue_scripts' );

function tsg_login_headerurl()
{
    return get_bloginfo( 'url' );
}

function tsg_login_headertext()
{
    return get_bloginfo( 'name', 'display' );
}

function tsg_site_icon_image_sizes( $sizes )
{
    $sizes[] = 140;
    
    return $sizes;
}

function tsg_login_enqueue_scripts()
{
    ?>
    <style type="text/css">
        body.login div#login h1 a {
            height: 140px;
            width: 320px;
            background-image: url(<?php echo get_site_icon_url( 140, get_bloginfo( 'template_url' ) . '/images/login-logo.png' ); ?>);
            background-size: contain;
        }
    </style>
    <?php
}

There are plugins available that perform this task for you, but I don’t think it’s necessary to add a plugin just for this.

Transparent PNG format images work best.

Update 2017

I have upgraded this script to use the Site Icon. You just need to upload your image using Appearance > Customise > Site Identity.

Update 2019

WordPress deprecated ‘login_headertitle’ in favour of ‘login_headertext’.