Before you get started with li3, it's important to know how your application's main folder is structured, and where everything should go. Clone yourself a copy of the main repo, and you'll find an app folder structure that contains:
Let's tackle each of these folders one-by-one, covering what each is used for, and how you can best organize your application.
config folder contains three main pieces: bootstrap files, your connections information, and your routes definitions.
The main bootstrap file in the config folder is
bootstrap.php. This file is second file PHP will execute in any request cycle, and it loads up the li3 framework along with any other extras that you define there. As such, it's a great place to place initial application configuration.
The best practice for bootstrapping parts of your application is by writing specific bootstrap files and placing them in
config/bootstrap/filename.php. Once written, include the configuration into the main bootstrap file:
// Adding my custom configuration or initialization...
require __DIR__ . '/bootstrap/myconfig.php';
connections.php file in config lists the connections you have to external data resources, most often some type of database.
Connections should be listed in this file, as calls to
Connections::add(), like so:
'type' => 'database',
'adapter' => 'MySql',
'host' => 'localhost',
'login' => 'root',
'password' => '',
'database' => 'my_blog'
'type' => 'http', 'adapter' => 'CouchDb', 'host' => '127.0.0.1', 'port' => 5984
Connections::add('mongo', ['type' => 'MongoDb', 'database' => 'app']);
The particulars on the adapter will shape how the connection definition is put together, but this list should constitute what you've got in
Routes definitions is how you inform the framework how URLs and bits of code match up. At the most basic level, it's how you tell li3 which controller should respond to a request to a given URL.
For example, I could specify that any request to
/login is handled by
UsersController::login() like this:
Router::connect('/login', ['controller' => 'users', 'action' => 'login']);
More on routes later, but this file should house all such configuration information.
Application controllers are housed here. Each controller is named in CamelCased, plural format (i.e.
PostsController.php), and placed here.
The extensions folder is meant to store extension classes that you've created for your application. Custom helpers, adapters, console commands and data classes.
A number of li3 classes extend the
lithium\core\Adaptable static class. This class allows you to take a number of different approaches and easily switch out implementations for an application task. Authentication, session handling, and caching are a few examples of li3 functionality that have been made adaptable.
Custom application adapters should be placed in this folder, organized by subfolder. For example, if I created a custom adapter for the
Auth class, based on my LDAP setup, I'd create the implementation in
Custom console applications are placed in
command. Commands you create should be built similar to those you see in
As an example, say I created a custom mailer queue, and I need to create a command to fill up the queue with announcement emails and trigger the send process. I'd create a new class called
QueueFiller that extends
lithium\console\Command, and place it in
Once there, running
li3 queue-filler from the command line will trigger the logic I've written.
Occasionally a new application will require custom data classes to work with a storage engine not already accommodated for by core classes.
If you've got some proprietary database, and it's result objects or query structures are very customized, you'll extend the classes in the
lithium\data namespace (i.e.
source\Http) and place them here for use in your application.
Custom view helpers are common need. These classes should extend
lithium\template\Helper and be placed in this folder.
libraries folder is meant to house entire li3 applications—or plugins—that your main application makes use of.
Third-party, non-li3 libraries should be placed here as well. If you're integrating with Facebook, or using part of the Zend Framework in your application, place those files here as well.
Application models are stored here, in CamelCased, plural naming format (i.e.
The resources folder is used by a li3 application as a non-web viewable storage place for application data. By default globalization files (such as
.po string files) and temporary application files are stored there.
As you build your application, the
resources folder is a great place for other application data like custom cache files, SQLite databases, or a temporary spot for uploaded files.
resources is a place where the web server has write access, so make sure to keep that in mind when securing your application.
tests folder is where the unit testing framework files for your application reside. The testing setup for li3 is covered elsewhere, but let's cover what ends up in each of the testing subfolders here.
All of the actual unit testing logic for the main MVC classes in the application go in the
cases folder. Subfolders should already exist inside of
cases to prompt you where each sort of test case should go.
Unit tests in the
integration folder test the interaction between two or more classes, or abstract class implementations.
mocks are used to facilitate certain unit tests. For example, if I'm testing a custom model I've created, I can create a new class in
mocks/data/MockSource.php and use it in my model unit testing logic.
It is recommend that you use subfolder organization that mimics your application's and li3's namespacing and folder structure.
views folder contains any pieces of view-level code in your application. The two main core folders here to note are
layouts. Other view folders here contain views organized by controller name.
Elements are small bits of view code that are used in multiple views. A common navigational element, menu, or form might end up as an element in this folder. Element files are suffixed with a compound extension: the first showing the type of view code, and the last as
Example element filenames might include
Views (and the elements they may contain) are rendered inside of view layouts. The layouts for your application reside in this folder, named similar to elements.
A layout named
default will be used to render a view if none other has been specified by the controller.
Along with the
layouts folders, many other controller-specific view folders will reside here.
One default example is the
pages folder here that holds all the views for the core
PagesController. As you create new controllers and views for your application, create new folders here, named after your controllers.
webroot folder of your application is (ideally) the only place in your application that is web-visible. The
index.php file takes care of bootstrapping li3, and the rest of the folders and files here are used for static content delivery.