You are viewing revision #8 of this wiki article.
This version may not be up to date with the latest version.
You may want to view the differences to the latest version or see the changes made in this revision.
In this article, we describe the directory structure used by yiiframework.com - the official Yii framework website. While this structure may look overly complicated for small projects or may not be optimal in some sense, we believe it is appropriate for medium or large projects in a team development environment. In fact, we have successfully used the similar structure in some other big projects.
Overall Structure ¶
Below is the directory structure we are using:
/
backend/
common/
components/
config/
params.php
params-local.php *
lib/
Pear/
yii/
Zend/
migrations/
models/
Comment.php
Extension.php
...
console/
commands/
SitemapCommand.php
...
config/
main.php
main-local.php *
params.php
params-local.php *
runtime/
yiic.php *
frontend/
components/
config/
main.php
main-local.php *
params.php
params-local.php *
controllers/
SiteController.php
...
lib/
models/
ContactForm.php
SearchForm.php
runtime/
views/
layouts/
site/
www/
assets/
css/
js/
index.php *
yiic
yiic.bat
In a team development environment, we should have some source code revision system (e.g. SVN, GIT) to manage the above structure. File names annotated with an asterisk should NOT be put in the revision system, as we will explain shortly.
Top-level Directories ¶
At the top level, we have four directories:
backend
: the backend application which is mainly used site administrators to manage the whole system.frontend
: the frontend application which provides the main interfaces to our target end users.console
: the console application that consists of the console commands needed by the system.common
: the directory whose content are shared among the above applications.
As we can see, we divide the whole system into three applications: backend
, frontend
and console
. If needed, we can add more applications (e.g. api
, to provide Web API service). We use common
to store files that are shared among the applications.
Application Directories ¶
The directory structure of each application is very similar. For example, for frontend and backend, they both have these directories:
components
: contains components (e.g. helpers, widgets) that are only used by this applicationconfig
: contains the configuration used by the applicationcontrollers
: contains controller classeslib
: contains third-party libraries that are only used by this applicationmodels
: contains model classes that are specific for the applicationruntime
: stores dynamically generated filesviews
: stores controller actions view scriptswww
: the web root for this application
The directory structure for console
is slightly different as it does not need controllers
, views
and www
. Instead, it contains a commands
directory to store all console command class files.
The Common Directory ¶
The common
directory contains the files that are shared among applications. For example, every application may need to access the database using ActiveRecord. Therefore, we can store the AR model classes under the common
directory. Similarly, if some helper or widget classes are used in more than one application, we should also put them under common
to avoid duplication of code.
To facilitate the maintenance of code, we organize the common
directory in a structure similar to that of an application. For example, we have components
, models
, lib
, etc.
As we will soon explain, applications may also share part of the configurations. Therefore, we also store the common configurations under the config
directory in common
.
When developing a large project with a long development cycle, we constantly need to adjust the database structure. For this reason, we also use the DB migration feature to keep track of database changes. We store all DB migrations under the migrations
directory in common
.
Application Configurations ¶
Applications of the same system usually share some common configurations, such as DB connection configuration, application parameters, etc. In order to eliminate duplication of code, we should extract these common configurations and store them in a central place. In our setting, we put them under the config
directory in common
.
When working in a team environment, different developers may have different development environments (e.g. operating system, directories, DB connections). These environments are also often different from the production environment. In order to avoid interference among developers, we divide the configurations into two parts: the base configuration (e.g. main.php
, params.php
) and the local configuration (e.g. main-local.php
, params-local.php
).
The base configuration should be put under version control, like regular source code, so that it can be shared by every developer.
The local configuration should NOT be put under version control and should only exist in each individual developer's working folder. A developer has full freedom to modify his local configuration.
In the application's bootstrap script index.php
, we can merge the base and local configurations and then configure the application instance, like the following:
require('path/to/yii.php');
$local=require('path/to/main-local.php');
$base=require('path/to/main.php');
$config=CMap::mergeArray($base, $local);
Yii::createApplication($config)->run();
Path Alias ¶
To facilitate referencing files in different applications, we also declare a root path alias site
which points to the root directory containing the four top directories. As a result, we can use site.frontend.models.ContactForm
to reference the ContactForm
class declared in the frontend
application.
Deployment ¶
During development or after finishing a project, we need to deploy it to the production server. Instead of uploading files to the server using FTP or other similar services, we can use revision control system to do the deployment.
We can treat the production server as a special developer who has the production server as his development environment.
We first check out an initial copy or update an existing copy from the revision control system to the desired location on the production server.
We then create or modify the local configurations specific for the production server. For example, we may need to adjust the DB connection parameters. We may want to define YII_DEBUG
to be false in index.php
.
Because we store each application in a separate directory, if needed, we can deploy them to different servers.
deploy applications to different servers ?
how to access Common Directory files when deploy applications to different servers ?
Re: deploy applications to different servers ?
The common directory contains code that is accessed by frontend and backend
So if you want to deploy the backend to a different server then the frontend, you need to deploy the common folder too.
Phing
I would also suggest using Phing to handle the full deployment process by creating environment skeletons (dev/stage/prod for example).
This way you could have dev-config.php, prod-config.php etc, and based on the build type you change your index to include the appropriate config, delete unsued configs, etc.
capistrano
Also i suggest Capistrano (writted on Ruby) as another solution for painless deployment.
yiic xwebapp /mydir?
I really like that type of directory structure, is there an yiic command to create such a structure?
Where is the protected folder then ?
hi, I am confuse about this directory structure. where is the protected folder ?
thanks!
@revo110, @qiang
@revo110
The protected directory is not required because everything in it is now outside the web root /frontend/www.
@qiangc
With the migrations directory in /common, when I change the yiic base path to /common and run the migration command, I get an error about the commands directory is not found. Therefore I have to move the /console/commands to /common/commands to generate migrations in /common/migrations.
migration path
@agentshark: instead of changing the basePath for console commands, you can configure the "migrationPath" property of MigrateCommand. In particular, you can do this by configuring 'commandMap' in your console app config.
Sandbox?
A sandbox containing this structure would be nice.
Create Directory Structure
@lightglitch
I found this to be useful ;)
or if you prefer, you may use the top level directories down approach:
Translations
There not mentioned translations, where i need to put all translations, and how to set in configuration? i tried save translations in /common/messages/ but backend or frontend applications can't access to that directory.
bellow is part of common/config/main.php
'message'=>array( 'class' => 'CPhpMessageSource', 'basePath'=> 'site.common.messages', )
also i tried and not worked. :?
'message'=>array( 'class' => 'CPhpMessageSource', 'basePath'=> dirname(__FILE__) . DS . '..'. DS . 'messages', )
Few things left to be cleared.
Hi I do not see where did you include the main.php(from the common config folder) in the bootstrap file of the frontend application(index.php)?
And I assume, that the backend application will have its own bootstrap file with the same name e.g: index.php, right?
Thank you!
A sandbox
Hi I tried to do this configuration to build a cms but i have some issues espacialy with the assets sttuf a sandbox for this organisation will be appriciated. Good article.
Entry script
Qiang,
Something is not clear to me, does each application have its own entry script under /www ??
e.g
index.php for the frontend app,
admin.php for the backend app, etc
what is a difference between this?
I am doing this now :
http://www.yiiframework.com/wiki/63/organize-directories-for-applications-with-front-end-and-back-end-using-webapplicationend-behavior/
What is the main difference between this setup? I am too new to see the bigger picture..
Look good for bigger projects
I like this folder structure idea, it look for me more natural to have backend folder for all administrative tasks, then using module. Off course this have sense only for bigger projects, because it will take some time to setup this structure, and more time to maintain/deploy it.
Tests?
What about tests? Should i create separate standalone application called
tests
for them or just createtests
folder in each application directory? Which solution will be painless and extendable?modules url
Hi all,
I am implementing this structure on my project but I have an issue with a module, how can I redirect from backend to a controller on ..common/modules/app/controller ?
i expect you understand what I am talking
What about Gii?
I'd like to use this structure but would like to keep using Gii as well. Is it possible?
Suggestions for Path Aliases
This is a great article and we are using this structure in a business application.
A suggestion I have regarding the Path Alias is to use 'root' instead of 'site'.
The reason for this is we have a module named 'site', so attempting to use an alias of something like 'site.common.models.*' inside of an application that has a site module, would be ambiguous and choose the module over the root path incorrectly.
Instead, we can do the following at the top of each application's config file:
Yii::setPathOfAlias('root',realpath('../../'));
Then, within the config file:
'import'=>array(
'root.common.components.\*', 'root.common.models.\*', ...
)
Getting confuse
Instructions are not so clear creating to much confusions. please upload a video if can or provide a proper documentation for same according to latest yii version.
there is an example of this architecture?
please give me a link to the source code
Sample/Source
Would be greate to have working source or more detailde tutorial of this architecture.
It's possible to use it on shared hostings and how?
Sample setup
Quick steps to setup your environment:
1) Create a root folder and subfolders : common, console, backend and frontend. You can use the folder structure given above.
Tip : In the root folder you can use "yiic webapp frontend" to create folders quickly, then just make some organization inside frontend folder.
2) Copy yii inside common/lib. Don't forget to edit your frontend and backend /www/index.php files to point yii installation folder.
3) Edit your config files. I've some additional lines on backend main.php:
Yii::setPathOfAlias('root', $root); Yii::setPathOfAlias('common', $root . DIRECTORY_SEPARATOR . 'common'); .. .. 'import' => array( 'common.components.*', 'common.extensions.*', 'common.models.*', .. ..
If you're using local config files, use CMap::mergeArray to merge configs ( explained in the article )
If you want to use Gii just enable it in main.php. You can create files in common ( e.g. enter common.models as model path )
4) For apache do some virtual host configuration :
FRONTEND :
<VirtualHost *:80> DocumentRoot "c:/wamp/www/root/frontend/www" ServerName sp.com ServerAlias www.sp.com </VirtualHost>
BACKEND :
<VirtualHost *:80> DocumentRoot "c:/wamp/www/root/backend/www" ServerName admin.sp.com </VirtualHost>
On windows you need to add following to your hosts file:
127.0.0.1 sp.com 127.0.0.1 admin.sp.com
If you're on production, don't forget to add subdomain to your DNS conf ( CNAME or A record )
That's all. Now you can access your frontend : www.sp.com and Backend: admin.sp.com
Themes folder
with this structure, where the themes folder should be put? I applied this structure for my project, and it seems themes folder is supposed to be placed in backend/www/themes or frontend/www/themes, but I want to move it to backend/themes or frontend/themes. I tried to change config.php file but it doesn't work
@Hieu Vo
Themes folder should be under frontend/www/themes and backend/www/themes, and you will want to setup your document roots to frontend/www and backend/www, so no files outside of www folders can't be accessed via web.
BTW, why you would want to place theme folders under frontend/themes and backend/themes?
What about shared (common) modules?
I do have a module that should be used both in admin and site areas (SRBAC, access control module). I think that it should be in the "common/modules/" folder. But, how can I load it from the backend or frontend application? Should I change the modules folder? If yes, how can I do this? I tried 'modulePath'=> $common.'/modules' in the backend config file but it didn't work.
Edit (solved):
The following changes (in main.php) solved my problem:
Yii::setPathOfAlias('srbac', $root.'/common/modules/srbac');
and
'modules'=>array( 'srbac' => array( 'class' => 'common.modules.srbac.SrbacModule',
themes and extensions
don't suppose theres any clean way to put a theme in the common dir and use it for multiple apps? My 'admin' app and my 'user' apps will use the same theme but my 'frontend' app will use something else.
Update
i achieved this by using in my common config:
'themeManager' => array( 'basePath' => '/xampp/htdocs/myapp/common/themes/', 'baseUrl' => 'http://static.myapp.com/themes/', //this is the important part, setup a subdomain just for your common dir ),
and in my apps i use simply: 'theme' => 'whatever'
how user gii?
I add configuration in frontend/config/main.php like this:
'modules'=>array(
// uncomment the following to enable the Gii tool 'gii'=>array( 'class'=>'common.lib.Yii.gii.GiiModule', 'password'=>'000', // If removed, Gii defaults to localhost only. Edit carefully to taste. 'ipFilters'=>array('127.0.0.1','::1'), ), ),
but i still cannot use gii,why?
can someone give me some steps how use gii?thanks.
common folder
does anyone has implemented a common/uploads or images folder and reference it from backend / frontend
any solution how to.
RE:common folder
I have implemented by creating upload folder in frontend. For accessing image in backend put a param for frontend url.
i.e if you frontend is www.backend.com then keep it in params and generate url while accessing images in backend. In Frontend you can access it directly.
I don't know if it is the best way to do it, but it is working fine for now.
small projects
For small project I suggest to have a standart structure. Leaving admin part as a module for backend.
full example
hi
is there any full example or demo for this artical to understand it vere good
thank you
use theme in sub application
hi
if i have this structure
- themes - - mytheme - protected - stores - - 2 - - - index.php
how can i use my theme in index.php
can anyone help me
console needs views
This wiki states:
"The directory structure for console is slightly different as it does not need controllers, views and www."
I run a console command that sends emails. Many of the emails have .pdf attachments that are generated on the fly - needing views.
So how do you access frontend/views/* from console?
@Gerhard Liebenberg: You could use a root alias
You could define a
root
alias in yourconsole.php
and then use:$views = Yii::getPathOfAlias('root').'/frontend/views';
See also http://www.yiiframework.com/doc/api/1.1/CConsoleCommand#renderFile-detail
console needs views
Thanx Schmunk
I used:
Yii::setPathOfAlias('frontend', $root . DIRECTORY_SEPARATOR . 'frontend');
But rendering a view from inside another view (all views are in frontend and shared by frontend and console), I had to do something like this:
If($app == 'frontend') { $this->renderPartial('application.views.mail.templates.mail_Footer'); } If($app == 'console') { $this->renderInternal('frontend/views/mail/templates/mail_Footer.php'); }
Not sure why the difference in dots and slashes.
To be honest, I would prefer all views to be in common. Then they can be shared between frontend, backend and console.
common folder
does anyone has implemented a common/uploads or images folder and reference it from backend / frontend
any solution how to.
common uploads folder
does anyone has implemented a common/uploads or images folder and reference it from backend / frontend
any solution how to.
Common uploads folder
@Mr Usman I did it by creating symbolic links to the uploads folder on both the front and backends. This only works if you are allowed to create symlinks (couldn't on shared hosting).
deny from all and urlManager for removing www folder from frontend and backend
I have checked with yii new directory structure given by Qiang Xue. And it is amazing. But i have some doubts?
How to deny direct access or secure our protected directory like controller, models and other directory as we are doing in protected folder of default yii application by .htaccess?
How remove /frontent/www from generated urls using urlManager?
Where to place themes folder i think webroot is the right place for all application?
If anyone has developed this sturcture then give some tips and tricks about it.
.htaccess
Compare to Yii v2.0
It is interesting to read this article in light of the directory structure used in v2.0 of Yii. The directory structure of Yii v.20 (Advanced Example, especially) turned out to be so similar to the suggestions given here.
Now that I look at the author of this article, it makes sense. This was no doubt a precursor to the early thinking about v2.0 of Yii. Nice to see the evolution...
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.