-
Notifications
You must be signed in to change notification settings - Fork 7.6k
Multiple Applications via Symlinks
Without trying to replace the other great wiki article here: Multiple Applications, I thought this might be another unique way of addressing the problem. The article comes from a post I made in the forums here: multiple sites, 1 codebase, using symlinks (with smarty)
Now onto the meat ...
[b]MY REQUIREMENTS[/b]
My project called for a specific configuration of sites and applications:
[code] site #1: one application site #2: has both frontend and backend applications (will also operate on wildcard sub-domains) site #3: uses ssl with one application site #4: one application (internal access)[/code]
All 4 sites are heavily related ... and will often want to use the same models, libraries, helpers, views etc. Unfortunately CI doesn't give me a place to store these resources cross-application, and I really didn't feel comfortable editing or extending the core CI classes. That might have made upgrading the framework painful with later releases. I like the idea of just 'dropping in' a new system folder without worry.
[b]MY HOMEWORK (B-)[/b]
So as I was looking into CI initially, I found a lot of posts about running multiple-application sites. Overall, I got the impression that this was something CI 'could' do with tweaking (depending on your specific sites/applications) but wasn't particularly great at out of the box. Thankfully, CI is so easy to work with that there are a number of solutions to consider.
[b]Option 1:[/b]
One alternative was to run all my apps out of the same application folder, and just give them unique controllers ... I considered this but thought it might be difficult to keep site #1 from calling site #2's controllers by editing the urls. My sites needed to be fairly secure in this regard.
[b]Option 2:[/b]
Another alternative was to modify the loader of the CI core classes to include a new search path, essentially adding a Library level where cross-application code goes. This would have been the most attractive option if I felt more comfortable editing core files. But I don't ... ick! Hopefully CI adopts a similar solution officially in a later release.
Some related links on that method:
[url=http://www.jaaulde.com/test_bed/CodeIgniter/modLoader/]http://www.jaaulde.com/test_bed/CodeIgniter/modLoader/[/url] [url=http://codeigniter.com/forums/viewthread/49157/]http://codeigniter.com/forums/viewthread/49157/[/url]
And other options I won't get into right now ...
[b]MY BACKGROUND INFO[/b]
My situation is unique to me perhaps. I happen to own the box my sites are being hosted on, so all configuration options are available. My sites use the traditional php5, mysql5, apache2 on Free(as in beer)BSD. I can edit httpd.conf freely and create .htaccess files as needed.
[b]MY SOLUTION[/b]
[color=red]I found I was able to share a (parent) application folder (located outside each site's root) with a specific site's (local) application folder ... I did this by creating a series of symbolic links in each (local) application folder to represent the corresponding folders in my (parent) application folder ... [/color]
I literally matched symbolic links to parent folders exactly ... EXCEPT for the (local) application's 'controllers' folder, which was really the meat of each website.
It might be easier to show you the following folder hierarchy I used: [code] application/ my global application folder, where most the code goes CodeIgniter_1.5.4/ my CI installs system folder and other files, I leave the version number so that I can link to a new system in the index.php if needed for testing common/ an apache directory alias called common lets me link to subfolders here called img, js, css, file, etc. Having one folder with all my includes makes it easy to specify in an .htaccess file that CI should leave links alone with the word common in it. Smarty_2.6.18/ my smarty install, contains the actual libraries www_site1/ the site root for site #1 www_site2/ the site root for site #2 www_site3/ the site root for site #3 www_site4/ the site root for site #4[/code]
[b]A closer look at my (GLOBAL) application folder:[/b]
[code] cache SMARTY SPECIFIC FOLDER with write access config standard codeigniter configs SMARTY SPECIFIC FOLDER controllers NOT USED GLOBALLY - EACH SITE HAS ITS LOCAL CONTROLLERS FOLDER FOLDER IS ACTUALLY EMPTY errors standard codeigniter helpers standard codeigniter hooks standard codeigniter libraries contains a wrapper class called MySmarty.php for smarty useage models standard codeigniter templates SMARTY SPECIFIC FOLDER templates_c SMARTY SPECIFIC FOLDER with write access views standard codeigniter[/code]
[b]A closer look at my (LOCAL) application folders (EACH SITE HAS ITS OWN):[/b]
[code] cache symbolic link to parent config symbolic link to parent configs symbolic link to parent controllers ALL LOCAL SITE SPECIFIC CONTROLLERS GO HERE default controller is index.php as set in CI's global config errors symbolic link to parent helpers symbolic link to parent hooks symbolic link to parent libraries symbolic link to parent models symbolic link to parent templates symbolic link to parent templates_c symbolic link to parent views symbolic link to parent[/code]
[b]A closer look at my individual site's ROOT folders[/b]
[code]
.htaccess
(see below)
index.php
links to (local) application folder and global system folder
system folder can be changed in one place to reference a new CI install
applications
mostly contains symbolic links, but has a legit controllers folder[/code]
[b]A closer look at my sites individual .htaccess files:[/b]
[code] Options +SymLinksIfOwnerMatch
RewriteEngine on RewriteCond $1 !^(index\.php|common|robots\.txt) RewriteRule ^(.*)$ /index.php/$1 [L] [/code][b]TWEAKAGE:[/b]
A few small edits I made along the way.
[b]For SSL. [/b]
Since I have a single CI config file for multiple applications/sites I had to make a small change to the way the $config[base_url] was captured. It now prefixes the URL with the proper protocol if SSL is in use on that site.
[code]$config['base_url'] = (isset($_SERVER['HTTPS']) ? 'https://' : 'http://').$_SERVER['HTTP_HOST']."/";[/code]
instead of
[code]$config['base_url'] = "http://".$_SERVER['HTTP_HOST']."/";[/code]
[b]For Smarty.[/b]
In my (global) applications autoload.php file, I add the following:
[code]$autoload['libraries'] = array('mySmarty');[/code]
Then I create a class file in my (global) application/libraries folder (remember to edit the smarty path)
Found on the CI forums, thx to the author whoever you are!
[code] if (!defined('APPPATH')) exit('No direct script access allowed');
require_once(APPPATH . "../../Smarty_2.6.18/libs/Smarty.class.php");
/* |==========================================================
Code Igniter - by pMachine |
---|
www.codeignitor.com |
---------------------------------------------------------- |
Copyright (c) 2006, pMachine, Inc. |
---------------------------------------------------------- |
This library is licensed under an open source agreement: |
www.codeignitor.com/docs/license.html |
---------------------------------------------------------- |
File: libraries/Smarty.php |
---------------------------------------------------------- |
Purpose: Wrapper for Smarty Templates |
========================================================== |
*/ |
class MySmarty extends Smarty{
var $smarty;
function MySmarty()
{
$this->smarty = new Smarty();
$this->smarty->template_dir = APPPATH . "templates";
$this->smarty->compile_dir = APPPATH . "templates_c";
$this->smarty->cache_dir = APPPATH . "cache";
$this->smarty->config_dir = APPPATH . "configs";
$this->smarty->compile_check = true;
$this->smarty->debugging = true;
log_message('debug', "Smarty Class Initialized");
}
function assign($key,$value)
{
$this->smarty->assign($key,$value);
}
function display($template)
{
$this->smarty->display($template);
}
} [/code]
[color=red]I hope this is helpful for some, I appreciated having the forums as a resource to gather information from. CodeIgniter has a great community here. [/color]
Peace. :)