4

I'm not sure if I phrased this question correctly...

My wife and I have one blog, family.com in this example, that we both contribute to.

I would like family.com to show all blog posts.

me.family.com would show only posts I author and her.family.com would show only posts she authors. later, we will add kid1.family.com and so on...

further, sometimes she/I/we do projects that grow beyond one post. project1.com would show only all posts in the 'project1' category. However, unlike authors, only specific categories would have their own domain names.

wp-subdomains-revisited plus domain-mapping-system used together seem closest to what I am looking for but they're outdated and I'm sure I couldn't replicate them myself.

Edit 1: I found this wonderful answer by mikeschinkel: Multiple Domain Names - One WP Install (non-Multisite) - Default Each Domain name to Category Archive

Edit 2: I got mikeschinkel's code working on my site. Great! Now, I've been trying to modify it to work with subdomains as well. That has not gone so well - only a white page loads when my modifications are in place.

Edit 3: The site is loading again with working domains and subdomains! How exciting!

Next task is to have all links use their respective domain/subdomain. For example, a post holiday written by me and in category project1 should appear as family.com/holiday, me.family.com/holiday or project1.com/holiday depending on which sub/domain it's linked from. Any suggestions would be wildly appreciated!!!

(also, it will have to work with WPML -> me.family.com/holiday, when translated, should become her.family.com/休日/ ... frightening!)

Edit 4: Just to clarify, functionally this should be no different than viewing an individual author or category archive, the only difference being the archive will have it's own sub/domain.

Also, my TLD is .is... and my domain is my family name. That means my URL is halfway to being a sentence -> _adam.rabbit.is/...

The goal is to have a url specific to whatever relationship:
adam.rabbit.is/gardening
wife.rabbit.is/coding
rabbit.is/travelling

Edit 5: Updated code - mostly working now. I'm reluctant to mark it as solved because I haven't removed the base category or added separate header/title for each page... but as is this code works and solves the main question of the post. I hope someone else finds it useful :)

Edit 6: I found a nice plugin called wp-no-base-permalink which removes the category base. I updated the code to work with this plugin. Now if I type adam.rabbit.is/uncategorized it shows all uncategorized posts by me - exactly what I was looking for!

answer below...

4 Answers 4

2

wp-config.php

if ( is_alt_domain( $_SERVER['SERVER_NAME'] ) ) {
    $domain = str_replace( 'www.', '', $_SERVER['SERVER_NAME'] );
    define( 'WP_SITEURL', 'http://www.' . $domain );
    define( 'WP_HOME', 'http://www.' . $domain );
} else if (is_sub_domain( $_SERVER['HTTP_HOST'] ) ) {
    $domain = "{$_SERVER['HTTP_HOST']}";
    define( 'WP_SITEURL', 'http://' . $domain );
    define( 'WP_HOME', 'http://' . $domain );
} else if (! (is_main_domain( $_SERVER['SERVER_NAME']) ) ) {
    Header( "HTTP/1.1 301 Moved Permanently" );
    Header( "Location:http://family.com", true, 301 );
    exit;
}
function is_main_domain( $domain ) {
    $domain = $_SERVER['HTTP_HOST'] ;
    return strcmp( $domain, my_main_domain() ) == 0 ;
}
function is_sub_domain ( $domain ) {
    $domain = str_replace( my_main_domain(), '', $_SERVER['HTTP_HOST'] );
    return in_array( substr( $domain, 0, -1), sub_domains() );
}
function is_alt_domain( $domain ) {
    $domain = str_replace( 'www.', '', $_SERVER['SERVER_NAME'] );
    $domain = substr( $domain, 0, strrpos( $domain, '.') );
    return array_key_exists( $domain, alt_domains() );
}
function sub_domains() {
    return array(
        'me',
        'her',
        'kid1',
    );
}
function alt_domains() {
    return array(
        'project1' => 'com',
        'project2' => 'com',
        'project3' => 'is',
    );
}
function my_main_domain() {
    return 'family.com';
}

functions.php

// this seems to be important
update_option('siteurl','http://' . $_SERVER["HTTP_HOST"]);
update_option('home','http://' . $_SERVER["HTTP_HOST"]);

add_action( 'category_link', 'yoursite_category_link', 11, 2 );
function yoursite_category_link( $category_link, $category_id ) {
    $parts = explode( '/', $category_link );
    // if %category% in http://%domain%/%category%/
    // is in alt_domains() update the category_link
    if ( array_key_exists("{$parts[3]}", alt_domains() ) ) {
        $tld = alt_domains()[$parts[3]];
        $category_link = "http://www.{$parts[3]}.{$tld}/"; // Strip 'category/%category%/'
    }
    return $category_link;
}

add_action( 'author_link', 'yoursite_author_link', 11, 2 );
function yoursite_author_link( $author_link, $author_id ) {
    $parts = explode( '/', $author_link );
    // if %author% in http://domain/author/%author%/
    // is in sub_domains() update the author_link
    if ( "{$parts[3]}" == "author" && in_array("{$parts[4]}", sub_domains() ) ) {
        $author_link = "http://{$parts[4]}.family.com/"; // Strip 'author/%author%/'
    } else {
        $author_link = "http://family.com/author/{$parts[4]}"; // Strip 'author/%author%/'
    }
    return $author_link;
}

add_action( 'init', 'yoursite_init' );
function yoursite_init() {
    // Remove the canonical redirect to the category page
    // if %category% in http://%category%.%ext%/ is a blogger category
    if ( is_alt_domain( $_SERVER['SERVER_NAME'] ) || is_sub_domain( $_SERVER['HTTP_HOST'] ) ) {
        $parts = explode( '/', strtolower( $_SERVER['REQUEST_URI'] ) );
        if ( (count($parts) > 1) &&  ( array_key_exists("{$parts[1]}",alt_domains() ) || ( "author" == $parts[1] && in_array("{$parts[2]}", sub_domains() ) ) ) ) {
            remove_filter( 'template_redirect', 'redirect_canonical' );
        }
    }
}

add_action( 'template_redirect', 'yoursite_template_redirect' );
function yoursite_template_redirect() {
    // Redirect any http://%domain%.%ext%/%category%/ to http://%category%.%ext%/
    // and any http://%domain%.%ext%/author/%author%/ to http://%author%.%domain%.%ext%
    $parts = explode( '/', strtolower( $_SERVER['REQUEST_URI'] ) );
    if ( array_key_exists( "{$parts[1]}", alt_domains()) ) {
        $tld = alt_domains()[$parts[1]];
        wp_redirect( "http://www.{$parts[1]}.{$tld}/", 301 );
        exit;
    } else if ( 'author' == $parts[1] && in_array("{$parts[2]}", sub_domains() ) ) {
        wp_redirect( "http://{$parts[2]}.famliy.com/", 301 );
        exit;
    }
}

add_action( 'request', 'yoursite_request' );
function yoursite_request($query_vars) {
    // If %category% in http://%category%.%ext%/ is a blogger category set the
    // 'category_name' query var to tell WordPress to display the category page.
    if ( is_alt_domain( $_SERVER['SERVER_NAME']) || is_sub_domain( $_SERVER['HTTP_HOST'] ) ) {
        $category_domain = str_replace( 'www.', '', $_SERVER['SERVER_NAME'] );
        $category_domain = substr( $category_domain, 0, strrpos( $category_domain, '.' ) );
        $author_name = substr( $_SERVER['HTTP_HOST'], 0, strpos( $_SERVER['HTTP_HOST'], '.' ) );
        $parts = explode( '/', $_SERVER['REQUEST_URI'] );
        $category_name = "{$parts[1]}";
        if ( array_key_exists($category_domain, alt_domains()) ) {
            if ( strlen( $category_name ) < 1  ) {
                $query_vars = array( 'pagename' => $category_domain.'-page' );
            } else if ( term_exists("{$category_name}", 'category') ) {
                $query_vars = array(
                    'category__and' => array(
                        get_category_by_slug($category_domain)->term_id,
                        get_category_by_slug($category_name)->term_id
                    )
                );
            }
        } else if ( in_array( $author_name, sub_domains() ) ) {
            if ( strlen( $category_name ) < 1  ) {
                $query_vars = array( 'pagename' => $author_name.'-page' );
            } else if (term_exists("{$category_name}", 'category') ) {
                $query_vars = array(
                    'category_name' => $category_name,
                    'author_name' => $author_name
                );
            }
        }
    }
    return $query_vars;
}

And, of course, you also need to point your subdomains (or *) on your nameserver to your wordpress install. You also will need to add a Virtual Host (Nginx) for any other domains you are using... and you will need to set up CORS.

As a side note, this answer used in conjuction with my next answer/question - How to have a static category/author page? - should make my intentions of having one multi-faced site a little more clear :)

6
  • 1
    @PieterGoosen - got it Jan 6, 2015 at 18:21
  • Great, thanks for posting your solution to your own question. Enjoy :-) Jan 6, 2015 at 18:22
  • My Pleasure! :D Jan 6, 2015 at 18:25
  • @adammoore I am trying to get a similar setup don't have any experience with WordPress or PHP. Is there somewhere you have a more in-depth tutorial/ explanation? I don't want to just be copy-pasting code. Feb 9, 2020 at 12:05
  • 1
    @ustone07 sorry, it's been over 5 years. I'm afraid I haven't looked at this in quite some time! However, when I did this I had zero experience so it should be doable. But yeah, you'll have to work through it - I'm not sure if it will still work with current versions of WP. Feb 10, 2020 at 13:34
1

Is there some reason you need subdomains over "subdirectories" (I put that in quotes because it won't actually be a real subdir... read on)? This would be much easier if you wanted to go with family.com/me, family.com/her, family.com/project1, etc...

Going this route, you could create page templates that have custom loops in them using WP_Query and assign them to pages in the WP Admin. If you're using pretty permalinks, then you can name the page whatever you want and you'll have a nice looking link.

I honestly can't think of a way this would be possible with subdomains, but that's less of a WP question and more of a domain/server management question.

4
  • 1
    Yeah, actually, it may seem silly, but I would prefer subdomains... So I am adam rabbit and I like gardening, coding and writing and I talk to different people about each but want to maintain 1 identity. Ultimately, I would like my URL to be in this format - [Author].domain.com.[catagory]/[tag] - for example, I would give my gardening friend adam.rabbit.is/growing/wasabi - my friend would only see posts tagged 'wasabi' in catagory 'growing' and written by me... Maybe it's not possible but I haven't given up yet! Dec 31, 2014 at 15:39
  • What you probably need is an .htaccess rewrite rule then, but the way you describe it, it could get rather complex. RewriteEngine On RewriteCond %{HTTP_HOST} ^me.family.com$ RewriteCond %{REQUEST_URI} !^/me/ RewriteRule ^(.*)$ /me/$1 RewriteCond %{HTTP_HOST} ^me.family.com$ RewriteCond %{REQUEST_FILENAME} !-f RewriteCond %{REQUEST_FILENAME} !-d RewriteRule ^(/)?$ me/index.php [L] Something like this might work but it is completely untested... Dec 31, 2014 at 15:41
  • This link might help... stackoverflow.com/questions/10642426/… Dec 31, 2014 at 15:45
  • Ah, that looks great! I'll try it after the new year and report back! Thanks! Dec 31, 2014 at 15:49
0

The best way to achieve content separation between sites is to separate their DBs. As a rule of thumb it is easier to aggregate content the separate it, search, RSS feeds, social sharing, SEO might need to behave differently on different subdomain, and there is no way the kids will agree to the design imposed by the "old guys".

The easiest solution is to use wordpress in a network mode, and then wherever you need write or find a plugin that will automatically import content from the "source blog" to the right aggregation site.

4
  • In this case it's not really content separation as much as categorisation. functionally, it should be no different than viewing one author archive or one category archive. However, it makes things easier, as I pointed out in the above comment, if I can tell a friend to go to adam.rabbit.is/growing/wasabi. Also, the kid is 3 - she can do her own thing in time, but now we do diy projects together and I would rather leave her the option of being included. Jan 4, 2015 at 16:22
  • the content separation comes from 1. you want each to have its own domain name 2. You want some content to be displayed at one site and not in another. While technically it might be possible to limit the visibility of content based on the domain name, it is mentally harder to think in this way, and it is easier to think in terms of aggregation. Jan 5, 2015 at 13:48
  • You're just wrong. see answer above. Jan 6, 2015 at 4:08
  • yes, two writes to the DB on each page load are the best way to code a site (if you really need it then something is terribly wrong with your code). Just because you can hack something to work, doesn't mean that it is the best long term way to code your site. Jan 6, 2015 at 20:07
0

Admittedly a clever solution, and one that works fine within the scope of your original question. For future readers with similar use cases' reference though I would suggest they also consider creating a multisite (network) install.

When used purely for sub domain sites (ie no domain mapping) it's not greatly more difficult to create and manage than a standard install. You then have a far wider scope to develop each sub site as you like in the future, and much more flexibility (entirely different themes etc.). Not to mention a more logical and easy to manage arrangement of content. Multisite is also far more extensible - add domain mapping and you can add your business site, other friends, sports groups etc on the one hosting account and admin log on.

The ThreeWP Broadcast plugin is a great solution for publishing posts on whatever sites are suitable for the topic etc, and some background reading on that will demonstrate the scope of multisite.

Just my feeling that most traffic to this post (due to the title) in the future will be people for whom multisite is a good fit but one that's often overlooked.

http://codex.wordpress.org/Create_A_Network

http://plugins.plainview.se/threewp-broadcast/

3
  • Yep, your probably right. In my case I want essentially one site with multiple faces. Anyone wanting more than one site, and I, should I want to make a separate site, should definitely look at doing just that.. perhaps with multisite even! Also, I'm sorry, I don't see how the title is confusing but I would be happy to fix it! Jan 8, 2015 at 14:52
  • when my site is less lame and has more posts than just "hello world" I'd be happy to share it. I hope at some point someone will tell me that this wasn't a bad approach! Jan 8, 2015 at 14:55
  • As I said - nothing wrong with using your own solution. Also I don't believe there's anything 'wrong' with the title - just that it inherently will catch a fair bit of traffic where a balance of answers is useful. I think a lot of people believe multisite installs to be far more difficult to manage and only for the likes of wordpress.com, when in fact it's equally suitable for individuals.
    – Steve82
    Jan 8, 2015 at 15:02

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.