Subdomaining with Cake
In this article, following a practical approach to subdomaining, we will make one model available through subdomains. Can be inspiring for alternative uses.
Inspired by the Hosting Admin URLs on a Subdomain at http://bakery.cakephp.org/articles/view/hosting-admin-urls-on-a-subdomain, I have tried to come up with some piece of code that makes uses of subdomains in an elegant way.
The aim is to access all instances of a model through subdomains. For instance, every user may have their subdomains, accessible at username.example.com
In order to deal with this, I assume that you already made the necessary implementations in your controller. Some sample code would look like (user_controller.php) :
Also, you need to route your users model at app/config/routes.php with something like:
Now, what we will actually do is run some piece of code before the MVC implementation is started. The correct place to do this is the app/config/bootsrap.php
bootstrap.php :
This piece of code is pretty self explanatory. if the subdomain is different than "www", the page displayed is users//. So, mumchamber.example.com/about is actually displaying the url www.example.com/users/mumchamber/about
To test subdomains on localhost, you may want to have a look at http://digitalpbk.blogspot.com/2007/01/making-subdomains-on-localhost.html Only remember that in linux, your hosts file is probably located at /etc/hosts
Also, you may want to see http://httpd.apache.org/docs/1.3/vhosts/ for virtual host documentation
The aim is to access all instances of a model through subdomains. For instance, every user may have their subdomains, accessible at username.example.com
In order to deal with this, I assume that you already made the necessary implementations in your controller. Some sample code would look like (user_controller.php) :
function view($unique_title){
$this->set('users', $this->User->findByUniqueTitle($unique_title) );
}
Also, you need to route your users model at app/config/routes.php with something like:
Router::connect('/user/*', array('controller' => 'user', 'action' => 'view'));
Now, what we will actually do is run some piece of code before the MVC implementation is started. The correct place to do this is the app/config/bootsrap.php
bootstrap.php :
$subdomain = substr( env("HTTP_HOST"), 0, strpos(env("HTTP_HOST"), ".") );
if( strlen($subdomain)>0 && $subdomain != "www" ) {
$_GET["url"] = "user/" . $subdomain . "/" . (isset($_GET["url"]) ? $_GET["url"] : "");
}
This piece of code is pretty self explanatory. if the subdomain is different than "www", the page displayed is users/
To test subdomains on localhost, you may want to have a look at http://digitalpbk.blogspot.com/2007/01/making-subdomains-on-localhost.html Only remember that in linux, your hosts file is probably located at /etc/hosts
Also, you may want to see http://httpd.apache.org/docs/1.3/vhosts/ for virtual host documentation

let's say you have:
username.domain.com and want to be able to make a page like:
username.domain.com/friends
username.domain.com/blog
How would this be done ? Does the router needs an extra line for this or can it be done in the user_controller.php using an extra view per function ?
Thanks
preg_match('/^(?:www\.)?(?:(.+)\.)?(.+\..+)$/i', env('HTTP_HOST'), $matches);
define('SUBDOMAIN',empty($matches[1])?false:$matches[1]);
define('HOST',$matches[2]);
define('BASE_URL','http://'.HOST);
if(SUBDOMAIN) $_GET['url'] = 'users/view/'.SUBDOMAIN.(isset($_GET['url'])?'/'.$_GET['url']:'');
It works with or without www. in front of the URL. It also snags the HOST (without subdomain) because you're probably going to want to use it around the site to remove the subdomain from your links when you don't need it.
Thanks
However, when I introduce named parameters - I immediately get a 403 Permission Denied from Apache. This is odd because if I directly access the controller/view/ in the URL even ith the named parameters it works fine.
Thus, I have set things up according to this article such that:
http://username.localhost/cakejunction/ essentially goes to:
http://localhost/cakejunction/partners/username/load/
Works great. However, If I add named parameters to the URL like this:
http://username.localhost/cakejunction/p1:page1/p2:value2 I immediately get a 403 - Permission Denied from Apache.
What is interesting, is if I use the direct equivalent URL that this would have translated into:
http://localhost/cakejunction/partners/username/load/p1:page1/p2:value2
It works fine.
So - I conclude that it is likely some combination of the subdomaining mechanism, the named parameters with colons and the Apache configuration.
WinXP
PHP5
Apache 2
Cake 1.2
i think it will help me a lot on my 'blogging' project.
currently, i am working on a 'social bookmarking' project. will try to implement your code so that users bookmarks can be accessed from user.sitename.com ;)
$url_parts = explode('.', env('HTTP_HOST'));
foreach($url_parts as $part) {
if(!in_array($part, array('www', 'example', 'com'))) {
$ident = $part;
}
}
RewriteEngine On
RewriteCond %{HTTP_HOST} ^(www\.)?(([a-z0-9_-]{1,100})\.)?example\.com$
RewriteRule ^(.*)$ /users/%3/about [L]
Regards