YiiBoilerplate ¶
We use this folder structure setup on Clevertech for our own projects and we thought it was worth sharing with the community.
Even though it looks complicated at the beginning, you will find that it is not that hard as it seems once you understand its structure. Yii's project structure wiki obviously inspired a lot of this setup, and you will find that some of the paragraphs here are taken from their wiki.
Hope you find it as useful as we do to develop your own projects.
Overview ¶
YiiBoilerplate, aims to provide Yii developers an application folder structure with sufficient flexibility to satisfy development needs from simple to enterprise applications.
It may look a little bit too complex at first sight but, at Clevertech, we understand that needs may vary along the development life cycle of a product in order to fulfill customer's requirements and that commonly forces developers to modify the initial folder structure, thus making very hard for a new developer to jump in and 'understand' where everything is located.
In order to avoid such time consuming tasks, ease the life of our beloved developers and increase productivity, we make use of this folder structure template for our projects.
Overall Structure ¶
Below the directory structure we are using:
/
backend/
components/
config/
environments/
main-private.php *
main-prod.php
params-private.php *
params-prod.php
main-env.php *
main-local.php *
main.php
params-env.php *
params-local.php *
params.php
test.php
controllers/
SiteController.php
...
extensions/
behaviors/
validators/
lib/
models/
FormModel.php
...
modules/
runtime/ *
views/
layouts/
site/
widgets/
www/
assets/ *
css/
images/
js/
themes/
index.php
.htaccess
common/
components/
config/
environments/
params-private.php *
params-prod.php
params-env.php *
params-local.php *
params.php
data/
extensions/
behaviors/
validators/
lib/
Behat/
Pear/
Yii/
Zend/
messages/
models/
widgets/
console/
commands/
components/
config/
environments/
lib/
migrations/
models/
runtime/ *
yiic.php
frontend/
components/
config/
environments/
main-private.php *
main-prod.php
params-private.php *
params-prod.php
main-env.php *
main-local.php
main.php
params-env.php *
params-local.php *
params.php
test.php
controllers/
extensions/
behaviors/
validators/
lib/
models/
modules/
runtime/ *
views/
layouts/
site/
www/
assets/ *
css/
files/
images/
js/
less/
index.php
robots.txt
.htaccess
tests/
bootstrap/
FeatureContext.php
YiiContext.php
features/
Startup.feature
behat.yml
INSTALL.md
README.md
runbehat
runpostdeploy
yiic
yiic.bat
When working in a team development environment, using any of the VCS (Version Control System) available (i.e. Git, SVN), the files and folders marked with an asterisk should not be included in the revision system.
Top Level Directories ¶
At the top-most level, we have:
- backend: the backend application which will be mainly used by site administrators to manage the whole system (avoiding admin modules at frontend application to avoid confusion)
- console: the console application that is compound of the console commands required for the system.
- frontend: the frontend application that is the main interface for end users. On a website development, this would be what the site users would see.
- common: the directory whose content is shared among all the above applications.
- test: the folder where we include all of our BDD system tests.
The whole application is divided into three applications: backend, fronted and console. Following the directory structure of the yii project site, with some twist on its configuration. The common folder is to store all files (extensions, components, behaviors, models, etc… ) that are shared among the mentioned applications.
Application Directories ¶
The directory structure of each application is very similar. For example backend and frontend both share the same directory structure with a slight variation at the www folder of the frontend and the inclusion of bootstrap theme and extensions for the backend, to easy the task to create Administrative panels.
The shared folder structure is this one:
- components: contains components (i.e. helpers, application components) that are only used by this application
- config: contains application specific configuration files.
- controllers: contains controller classes
- extensions: Yii extensions that are only used by this application
- lib: third-party libraries that are only used by this application
- models: contains model classes that are specific for this application
- modules: contains modules that are only used by this application
- views: stores controller actions view scripts
- widgets: stores Yii widgets only used by this application.
- www: the web root for this application.
We have created extensions and widgets folders, that could had been obviously included in the components folder, in order to clearly differentiate the types of components that could exist into a Yii application and easy the task to find them. So, for example, developers won't search for a widget that renders a jQuery UI plugin within a folder that has application wide components, or helpers, or extensions, or…
The directory structure for console application differs from the others as it doesn't require controllers, views, widgets, and www. It has a commands directory to store all console command class files.
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 console.
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.
- source: Yii Framework Site
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.
How to configure the application ¶
The configuration for this boilerplate is not that complicated as it seems at first sight. As mentioned before, if our system has both backend and frontend applications and they both share the same DB configuration. We just need to configure one of the files on the config sub-directory under the common folder.
The files within the config folder of each application and common folder requires a bit of explanation. When working in a team environment, different developers may have different development environments. These environments are also often different from the production environment. This is why the configuration folders on each application contains a list of files that try to avoid interference among the different environments.
As you can see, the config folders include a set of files:
- environments/params-private.php: This is to have the application parameters required for the developer on its development environment.
- environments/params-prod.php: This is to have the application parameters required for the application on production
- environments/main-private.php: The application configuration settings required for the developer on its development environment.
- environments/main-prod.php: The application configuration settings required for the application on production
- main-env.php: This file will be override with the environment specific application configuration selected by the runpostDeploy script (as we are going to explain after)
- main-local.php: This is the application configuration options for the developer*
- params-env.php: This will be override with the environment specific parameters selected by the runpostdeploy script
- params-local.php: The application parameters for the developer*
- params.php: The application parameters
- test.php: Test application configuration options
The configuration tree override in the following way:
local settings > environment specific > main configuration file
That means that local settings override environment specific and its result override main configuration file. And this is true for all configurations folders being the common configuration folder settings predominant over the application specific one:
common shared params > application params common shared config > application config
There is a slight difference between the **-private.php* and the **-local.php* files. The first ones are automatically read with the runpostdeploy*** script and it could be settings that developers sitting on same machines in internal networks, and the latest is the programmer's configurations.
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 developer's working directory.
The runpostdeploy script ¶
The project has a very useful script that automatically creates the required and not shared folders for a Yii application: the runtime and assets folders, extracts the configuration settings specified for a specific environment and copies them to the *-env.php files and runs migrations when not on private environments -we believe that migrations should be always run manually by developers on their machines.
From the application's root folder, to run the script simply do:
./runpostdeploy environmentType migrations
- environmentType (required): can be "any" of the ones you configure on the environments folders (i.e.
./runpostdeploy private
to use *-private.php configurations) - migrations (optional): could be "migrate"" or "no-migrate".
- migrate: will run migrations
- no-migrate: will not run migrations (on private wont run them anyway)
And that's it! You have now a solid structure with a ready to use Bootstrap like backend admin interface and a frontend with latest HTML5Boilerplate improvements.
Resources and Download ¶
Get the most up to date version from the Github repository!====
well-built beautifully designed web applications
www.clevertech.biz
update HTML5Boilerplate
hi
unfortunately HTML5Boilerplate has a bug in .htaccess file in gzip compression for new version of Apache and in new release version of HTML5Bilerplate the issue has been resolved it should be replace with:
# ---------------------------------------------------------------------- # gzip compression # ---------------------------------------------------------------------- <IfModule mod_deflate.c> # Force deflate for mangled headers developer.yahoo.com/blogs/ydn/posts/2010/12/pushing-beyond-gzipping/ <IfModule mod_setenvif.c> <IfModule mod_headers.c> SetEnvIfNoCase ^(Accept-EncodXng|X-cept-Encoding|X{15}|~{15}|-{15})$ ^((gzip|deflate)\s*,?\s*)+|[X~-]{4,13}$ HAVE_Accept-Encoding RequestHeader append Accept-Encoding "gzip,deflate" env=HAVE_Accept-Encoding </IfModule> </IfModule> # Compress all output labeled with one of the following MIME-types <IfModule mod_filter.c> AddOutputFilterByType DEFLATE application/atom+xml \ application/javascript \ application/json \ application/rss+xml \ application/vnd.ms-fontobject \ application/x-font-ttf \ application/xhtml+xml \ application/xml \ font/opentype \ image/svg+xml \ image/x-icon \ text/css \ text/html \ text/plain \ text/x-component \ text/xml </IfModule> </IfModule>
bug
in the last line of common directory part you store all DB migrations under migrations directory in console not common directory.
@ramram
Good catch!
If you look at our .htaccess you will see that in fact we are not using html5 boilerplate on but a modified version. Nevertheless, the best move is to do what you just pointed out.
Thanks... new html5boilerplate came today right?
@ramram
Done!
htaccess change -thanks ramram
multilanguage, config
Did you think to add multilingual support by default?
What do you think about this approach to app configuration - yii-environment, with some modifications, like common folder use?
@Alex.Sh
I think is an amazing extension, nevertheless, we thought that is much better to stick to static environment settings for different scenarios that will easy the task to create deploying commands.
But on a personal note, I really would like to see this in action with yii-environment, maybe a volunteer in our github?
Notes on YiiBoilerplate / common / components / WebApplication.php
Notes on YiiBoilerplate / common / components / WebApplication.php (A)
public function runController($route) { try { parent::runController($route); } catch (CHttpException $e) { if (@$_SERVER['REQUEST_METHOD'] == 'OPTIONS' && @$_SERVER['REQUEST_URI'] == '*') { Yii::app()->end('Hello, friend!'); } else throw $e; } }
Notes on YiiBoilerplate / common / components / WebApplication.php
Notes on YiiBoilerplate / common / components / WebApplication.php (B)
legibility!
public function getLocale($localeID = null) { try { return parent::getLocale($localeID); } catch (Exception $e) { return CLocale::getInstance('en'); } }
if one writes this
return parent::getLocale($localeID);
why not to write also :
return parent::getLocale('en_US');
instead of CLocale::getInstance('en_US');
You can interchange parent::getLocale and CLocale::getInstance; the note remains valid.
Notes on YiiBoilerplate / common / components / WebApplication.php
Notes on YiiBoilerplate / common / components / WebApplication.php (C)
public function getLocale($localeID = null) { try { return parent::getLocale($localeID); } catch (Exception $e) { return CLocale::getInstance('en'); } }
What if I misspelled LocaleID?
I think some sort of warning must be logged to the user in the catch...
Notes on YiiBoilerplate / common / components / WebApplication.php
Notes on YiiBoilerplate / common / components / WebApplication.php (D)
Abuse of exceptions
public function getLocale($localeID = null) { try { return parent::getLocale($localeID); } catch (Exception $e) { return CLocale::getInstance('en'); } }
In my opinion this code is just a flow control.
Is it possible to use this on a shared server?
Is it possible to use this on a shared server? And is it possible to use gii with it?
@abajja
All of that is good input, why not sharing your thoughts with us at github? Would be great to merge whatever changes you may consider in order to improve this setup for every one
@Fahd
Yes, you can! This is just a variation of a Yii's project setup. I recommend you that you use a shared hosting that allows to change your directory root so you can point to frontend/www for your site and then that allows you to have a subdomain to point to your backend -for example: admin.yourdomain.com, folder (backend/www)
Modules
Hi
Is there a right way to use modules that combine both backend and frontend features, like yii-user, forums, comments?
Modules provide greate reusability, for example in native structure I can create Blog as a module like this yupe-blog and copy-paste thrue all projects. Of coarse we can create modules in YiiBoilerplate, but need some more instructions and use cases. Can you think of adding one to article, or demo project?
yiiboilerplate and code separation
This extension looks very nice for separation of backend and frontend. How about code separation between dev, staging and live? It only addresses how to setup different DB connection for each environment. Are there any more examples or a forum thread to discuss the usage of this extension in depth?
Cheers
@Alex. Sh & @bettor
Alex:
As you know, you can configure the 'modulePath' property of your module. You could share modules on your 'common' directory and then those that are shared among apps, you set its 'modulePath' property to their location.
... 'modules'=>array( 'forum'=>array( 'modulesPath'=>'/var/htdocs/www/common/modules' // example ) ) ...
Bettor:
This project structure has two configurations on the 'environments' folder as an example. You could easily include on the 'environments' folder three different configurations: 'dev', 'stage', 'prod' like this:
params-dev.php
,params-stage.php
,params-prod.php
main-dev.php
,main-stage.php
,main-prod.php
Then, the only thing to do is run the 'runpostdeploy' command with the environment you wish (ie ./runpostdeploy stage will deploy the configurations on params-stage.php and main-stage.php into params-env.php and ain-env.php respectively)
code separation
Thanks Antonio for the explanation. What I am trying to understand is for example I have 3 environments dev/staging/production. On staging and production I run stable code that has been tested. However, on dev I would like to deploy newly developed code. For instance I make changes to my SiteController v2 and want to deploy it do dev only and still have the older SiteController version running on staging and production. How is this addressed in Yiiboilerplate?
Thanks in advance
Question about Yiibooster
I'm playing around with the Yiibooster code within the Boilerplate and am curious about the JSON Grid capability. I don't see anything in the documentation indicating what format the JSON grid is expecting for the data. Did I just miss something?
@bettor & @skidz7
a) @skidz7
Please, for JSON Grid docs visit YiiBooster site
@bettor
YiiBoilerplate is just a project structure configuration. The environments are there to hold different types of project configurations:
Then, to install the boilerplate you just use the
runpostdeploy environmentname
and will configure your application according to your environments configurations, nothing else.For your request, you can make use of
git
.Modules...
Hi,
I'm trying to set a "user" module on "common" but it gives this exception:
> Alias "user.UserModule" is invalid. Make sure it points to an existing PHP file and the file is readable.
The module is inside .../common/modules/ and in frontend/config/main.php I have:
'modules' => array( 'user'=>array( 'modulePath'=>'/var/www/mysite/common/modules', ), ),
Thanks for all the help.
Edit: forgot to say that if I move the module to ".../frontend/modules" and remove the "modulePath" from config it works ok.
Re: Modules
Ran into this today. Solution is to specify class instead of modulePath.
'modules' => array( 'user'=>array( 'class'=>'common.modules.user.UserModule', ), ),
Apparently class looks up the path alias first.
css
In the default instalation the "bootstrap.css" is executed first than "normalize.css" so this last one messes with the bootstrap css.
How do you fix this?
modulePath
Is it possible to add multiple modulePath to have few modules folders - base modules in common folder and one for backend and frontend? Load from common first.
How to prohibit accessing the directory?
The directory of backend can be visited? How to forbid it?
@chriscao
Set your server webroot folder to backend/www, and for frontend to frontend/www, and none of files outside www folders will not be visible from web.
@Ivica
Thank you...
@skidz7
I forgot to tell you that the JSON data is automatically handled by the grid. You do not need to do absolutely nothing but to configure the grid to render (check the docs), afterwards, the whole communication and data rendering is handled by the grid itself.
@NCS_One
That has been already fixed on github by the community.
Use html/css theme for frontend
You are using Yii themes for backend(there is bootstrap theme, but theme is not used, need to be configured in main.php config file), but why you don't use them for frontend too? It have more sense to use theme for frontend then for backend. I will add them easily for my project. Also I think that js/css/less/image should be inside theme/bootstrap folder.
README.md indentation
Hi Antonio!
I think there is a indentation problem in the "Overall Structure" : the first "config/", "controllers/" and "extensions/" should be inside "backend/".
BTW, it seems that both spaces and tabs are used inside the README file for indenting...
Cheers!
PHPUnit Problems
I'm trying to run PHPUnit tests on a project created with the boilerplate but getting errors. I'm assuming this has something to do with the different folder structure, because regular yiic-generated projects run tests just fine.
Any pointers for this?
@fleuryc
Thank you!
@Ivica
The reason why I put themes in the backend is because is normally there that we change the styling of our admin panel and the frontend is normally used to have the frontend design that could be anything totally outside from theming Yii...
User Table Schema
Hey Antonio. Nice job. This is what I was looking for to setup a new project. I'm searching on the code, here and google for schema of the user table with admin credentials. Can you help me?
@thiagovidal
Isn't it here? github repository user schema
I know that at the migration we shouldn't make use of models, that will be changed.
URL rules not working
Hi,
I've cloned github repo inside my webroot dir (apache mod_rewrite enabled),
Set RewriteBase to /YiiBoilerplate/backend/www (backend's .htaccess)
Browsed http://localhost/YiiBoilerplate/backend/www
and when i click on links about, contact or login i get a 404 error
http://localhost/YiiBoilerplate/backend/www/site/page/?view=about
http://localhost/YiiBoilerplate/backend/www/site/contact/
http://localhost/YiiBoilerplate/backend/www/site/login/
What I'm missing?
Regards,
Rodrigo
安装yii-user需要注意:
比如说yii-user安装在common/modules/,在backend使用yii-user时,
backend/config/main.php
以及
console/config/main.php
需要在下面添加一条:
'modules' => array( 'user' => array( # 添加下面这条,不然会报错。 'class'=>'common.modules.user.UserModule', ... ), )
另外修改:modules/user/controllers/ProfileFieldController.php
把:
Yii::getPathOfAlias('application.modules.user.views.asset');
修改为:
Yii::getPathOfAlias('common.modules.user.views.asset');
还有:
Yii::getPathOfAlias('application.modules.user.components');
修改为:
Yii::getPathOfAlias('common.modules.user.components');
祝你好运!
Forum Thread
@Rodrigo make sure in your apache config you have:
AllowOverride All
@Toni, should we make a forum thread for questions and answers as the comments here aren't meant for questions I believe...
Edit: Here's the forum thread for YiiBooster
Backend about.php
Hi Antonio,
In your backend application: you may add 'page' action to SiteController, since the latest version is asking the user to login in order to see the static about page.
How To Login Into Backend Yiiboilerplate
I have installed yiiboilerplate. I am on login screen of backend but I don't know the username / password?
yii 1.1.13, zend 2 migration
are your planing to migrate up to the latest yii 1.1.13 , zend 2.x, and YiiBootstrap 2.0.3 ... and when?
Thanks for the great effort
Test Config
I am trying to use the behat tests with Yii's built in CDbTestCase
In tests/bootstrap/FeatureContext.php, there is this comment.
"And your test config will be in
/common/config/test.php
file."Should I create this file by copying the one from either frontend or backend app? It looks like it will need to be changed as basePath will not work.
I would like to run tests on both frontend and backend apps though, hopefully using one behat command for ease of use in a CI server. Is it possible or will I have to switch between config files?
Cannot find the Yiic
When I run the command "runpostdeploy private migrate" in Windows command prompt, it shows error. "... Could not open the input file: "C:\root folder\common\lib/../../yiic".
The script can create directories. But when the script run the command "php 'C:\rood folder\common\lib/../../yiic' migrate --interactive=0, I encountered the above error.
Please suggest me how I can solve this issue.
Yii upgrade to 1.1.13
If i just replace yii to new version 1.1.13. will it create some problem to compatibility to
Yii Bootstrap?
Rights and User Ext
I have Install Rights and User Extensions,
Two questions.
First, let say if I logged in from the frontend as admin and then goes to backend. it redirect me to login screen again in the backend what can be the issue here.
Second, the rights extension, when I Generate items for controller actions, it only display controllers in the backend side, and doesn't have any ideas of the controllers in the frontend area. (now when the permission are apply in filter it will have no idea of this permission for the frontend section??)
Sorry my english or the question are bad formulate.
@leo4all
You need to understand that front end and back end are separate hence user authenticate is also separate.
IN case of rights, i have implemented it in backend and working fine.If you want to implement rights to backend and frontend do it separately. I am not sure if you can implement it in common section.
Zend Lucene
Hi,
I was using Zend Lucene and then I updated my folder structure to boilerplate. I realized that two folders were totally missing in Boilerplate original Zend/Search folder. Just want to tell the others if they face the same problem, they have to update at least that folder and replace all require_one in all php files in that folder.
Performance issue
I have setup boilerplate for a big project and i realized that boilerplate is very slow. So, what can i do for performance boosting ?
Does anyone facing the same performance issue.
Re:Performance issue
I don't know if the developer support this section or not, he is working on a new project called YiiWheels. You may disable the debug mode in index.php found in frontend/www. That might help specially if you're using the bootstrap extension.
maybe due to using less
isn't the overhead caused by activated less compilation ?
is there a way stop it when no changing were applied to css ?
is this still a project to follow or is there something new to wait for ?
PHPUnit Problems
Hi! I have the same problem:
"I'm trying to run PHPUnit tests on a project created with the boilerplate but getting errors. I'm assuming this has something to do with the different folder structure, because regular yiic-generated projects run tests just fine.
Any pointers for this?"
Thanks!
Re:Performance issue
I have removed bootstrap from preload, and now it's performance is much better.
Cant find out how to install it
Please, please, please
I can't install it.
The first I can't find "runpostdeploy" command anywhere on the system or unpacked archive.
If skipping that step I get error
Alias "bootstrap.components.Bootstrap" is invalid. Make sure it points to an existing PHP file and the file is readable.
And I don't have the folder "vendor" with necessary content in it. Anyway I've created it and put yii and yiiBooster there bu still not working.
Please, help me install it.
PS: working on 2 system, local Windows with XAMPP for production and remote linux for hosting.
Update: I figured out how to do it, just installing all dependencies with composer.
But now I have another question: Using gii i'm creating the models, Crud creates the Controllers extended from CController that don't work till changing CControler to BackendController. It's not a big deal but the views not showing correctly.
So again: How to work with YiiBoilerplate? How to write correct mvc? How to use common mvc elements?
If you have any questions, please ask in the forum instead.
Signup or Login in order to comment.