Yii 1.1: The directory structure of the Yii project site

97 followers

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 application
  • config: contains the configuration used by the application
  • controllers: contains controller classes
  • lib: contains third-party libraries that are only used by this application
  • models: contains model classes that are specific for the application
  • runtime: stores dynamically generated files
  • views: stores controller actions view scripts
  • www: 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.

Links

Russian version

Total 20 comments

#16665 report it
Gerhard Liebenberg at 2014/03/17 09:58am
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.

#16663 report it
schmunk at 2014/03/17 08:52am
@Gerhard Liebenberg: You could use a root alias

You could define a root alias in your console.php and then use:

$views = Yii::getPathOfAlias('root').'/frontend/views';

See also http://www.yiiframework.com/doc/api/1.1/CConsoleCommand#renderFile-detail

#16662 report it
Gerhard Liebenberg at 2014/03/17 08:41am
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?

#16515 report it
malkabani.com at 2014/03/01 09:08am
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

#16463 report it
malkabani.com at 2014/02/26 07:46am
full example

hi is there any full example or demo for this artical to understand it vere good

thank you

#15621 report it
R.K. at 2013/11/29 08:09am
small projects

For small project I suggest to have a standart structure. Leaving admin part as a module for backend.

#15619 report it
hemc at 2013/11/29 01:22am
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.

#15618 report it
leo4all at 2013/11/29 01:08am
common folder

does anyone has implemented a common/uploads or images folder and reference it from backend / frontend

any solution how to.

#14618 report it
gaoqingsiner at 2013/08/29 04:15am
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.

#11275 report it
nsanden at 2013/01/03 12:06am
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'

#10898 report it
Arivan Bastos at 2012/11/30 04:41pm
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',
#10375 report it
Ivica at 2012/10/24 01:40am
@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?

#9900 report it
Hieu Vo at 2012/09/20 01:24am
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

#9444 report it
mgk at 2012/08/11 05:42am
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

#9194 report it
Alex.Sh at 2012/07/27 05:11am
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?

#9157 report it
TBIKC at 2012/07/24 03:00pm
there is an example of this architecture?

please give me a link to the source code

#8891 report it
hnam at 2012/07/06 06:43am
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.

#7742 report it
Jason K at 2012/04/13 12:59pm
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.*', ... )

#7551 report it
JFReyes at 2012/03/29 10:57am
What about Gii?

I'd like to use this structure but would like to keep using Gii as well. Is it possible?

#6028 report it
isreal at 2011/12/06 02:40pm
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

Leave a comment

Please to leave your comment.

Write new article
  • Written by: qiang
  • Updated by: Yang He
  • Category: Others
  • Yii Version: 1.1
  • Votes: +81
  • Viewed: 115,690 times
  • Created on: Mar 7, 2011
  • Last updated: Mar 1, 2013
  • Tags: directory, config