Multiple domains for one symfony project, the basics, config file version
When I published my post about using a single symfony application to serve multiple domains using a database to store the site-specific data, there was some people to complain about the extra query you get on each request. Right. Using a (cached) config file instead is not that hard as long as you use it only to match a domain name against a numeric id. Storing more site-specific data is a bit more problematic, but we will solve this in a later post.
And because I'm lazy, I won't re-write the entire article, just highlight the differences between the two methods, so you might as well read the database version if you did not already.
Now, first thing, the config file. We will create a simple project-wide config file: /config/app.yml:
all: paris.carshop: 1 auckland.carshop: 2
Then we detect the site and add a generic sfConfig entry for it. This is done, as before, in /config/ProjectConfiguration.class.php. We will only change the detectSite() method to take advantage of the cached config information:
[php]
public function detectSite(sfEvent $event)
{
sfConfig::add(array('site_id' => sfConfig::get('app_'.$_SERVER['HTTP_HOST'])));
}
Easy heh ?
Now we just have to adapt the model classes to use this config entry. The CarTable::createQuery() method will look like:
[php]
/**
* Creates a query, adding the site criteria automatically
*
* @return Doctrine_Query
* @see Doctrine_Table::createQuery()
*/
public function createQuery($alias = '')
{
$query = parent::createQuery($alias);
$query->where('site_id = ?', sfConfig::get('site_id'));
return $query;
}
The Car::save() method:
[php]
/**
* Automatically populates the site_id field if necessary
*
* @see sfDoctrineRecord::save()
*/
public function save(Doctrine_Connection $conn = null)
{
if (empty($this->site_id))
{
$this->setSiteId(sfConfig::get('site_id'));
}
return parent::save();
}
And you're all set ! For the record, here are the other modified files from the last post:
config/doctrine/schema.yml:
Car:
columns:
site_id: { type: integer }
name: { type: string(255) }
description: { type: clob }
image: { type: string(255) }
data/fixtures/ now contains only the Car fixtures:
Car:
car_1:
site_id: 1
name: Peugeot 307
description: Lorem ipsum dolor sit amet, consectetur adipiscing elit.
car_2:
site_id: 1
name: Renault Laguna
description: Maecenas tortor nunc, aliquam et, ultrices id, ornare consectetur, mauris.
car_3:
site_id: 2
name: Subaru Impreza
description: Ut accumsan diam et orci. Sed sit amet neque ac diam rutrum iaculis.
Comments
Je cherche à faire ce genre de chose, mais j'ai besoin que pour chaque sous domaine, ça charge tout un tas de variables permettant de changer l'aspect ou le contenu du site. Sachant que je vais ajouté des sous domaines a l'avenir avec chacun leurs config, j'ai besoin d'un truc souple.
Pour le coup, j'avais 2 idées, mais je suis pas sûr de leurs conséquences :
## 1
Dans les fichiers yml, je créé des variables préfixées par le nom du sous domaine, et dans mon code, je teste automatiquement ces variables en fonction du sous domaine par lequel je suis entré (if sfConfig::get('app_'.$_SERVER['HTTP_HOST'].'_xxxx)...)
Je vais avoir pas mal de paramètres à écrire dans le yml pour chaque sous domaine, mais est ce vraiment grave ?
##2
Toujours en utilisant les fichiers yml (surtout le app.yml en fait), je crée des environnements différents pour chaque sous domaine, avec leur propres paramètres, et je fais le switch dans le index.php en changeant dynamiquement l'environnement passé à 'getApplicationConfiguration'.
Qu'en penses tu ?
PS : j'ai echappé les crochets de HTTP_HOST, il était pris pour un lien ^^
Je prépare un autre post qui explique comment faire ça. En gros, l'idée est d'avoir un fichier de conf par domaine, genre /config/sites/paris.carshop.yml, et de loader le bon (en gérant le cache de préférence).
Et aussi encore un autre post avec une autre méthode (database+cache)
En tout cas sache que c'est un sujet qui me préoccupe au plus haut point en ce moment, donc je risque de bloguer dessus encore un bon moment :-)
A la bonne heure ^^
Mais tu ne m'as pas dit ce que tu pensais de mes idées (surtout la 2ème ?) ;)
Ta solution #1 est ingérable en pratique je pense (si tu dois faire ça a chaque endroit où tu as besoin d'une variable spécifique au domaine tu vas galérer)
pour la #2, ça revient un peu au meme que ma solution, sauf que je preferre la mienne :-) là tu détournes un peu la notion d'environnement
Great article!
You said in December 2008, that you were going to cover domain specific layouts and other areas in a future article - have you had time to consider this yet?
What would be the best way to have site/domain specific layouts and perhaps actions and action templates in some cases(over-riding) default if exist. Is it possible to use themes with your method to arrange the directory structure to have layouts, actions & views for each domain whilst still leveraging your methods here for the site config with Doctrine?
Many thanks!
Duendon
Hi Duendon, I've had the occasion to work on a project involving about everything you mentioned, so I now have a greater insight at that sort of things that I'm going to share, but I'm not sure yet when I'll find the time to do so (especially since I have my talk at sflive to prepare).
I think I'll try to work out smaller articles focusing on more detailed points soon after sflive (that is after june 12th)
Hi,
I too would really like to hear about your insights. Will be looking forward to when you find the time :)