@title Phabricator Code Layout
@group developer

Guide to Phabricator code layout, including how URI mapping works through
application class and subdirectory organization best practices.

= URI Mapping =

When a user visits a Phabricator URI, the Phabricator infrastructure parses
that URI with a regular expression to determine what controller class to load.
For now, that regular expression is hard-coded inside the
@{class:AphrontDefaultApplicationConfiguration} within the ##getURIMap##
method. Use the existing entries as examples for adding your own entries.

The Phabricator infrastructure knows where a given controller class lives on
disk from a cache file the Arcanist phutil mapper generates. This mapping
should be updated whenever new classes or files are added:

  arc liberate /path/to/phabricator/src

Finally, a given controller class will map to an application which will have
most of its code in standardized subdirectories and classes.

= Best Practice Class and Subdirectory Organization =

Suppose you were working on the application ##Derp##.

  phabricator/src/applications/derp/

If ##Derp## were as simple as possible, it would have one subdirectory:

  phabricator/src/applications/derp/controller/

containing the file ##DerpController.php## with the class

 - ##DerpController##: minimally implements a ##processRequest()## method
   which returns some @{class:AphrontResponse} object. The class would probably
   extend @{class:PhabricatorController}.

If ##Derp## were (relatively) complex, one could reasonably expect to see
the following directory layout:

  phabricator/src/applications/derp/conduit/
  phabricator/src/applications/derp/constants/
  phabricator/src/applications/derp/controller/
  phabricator/src/applications/derp/editor/
  phabricator/src/applications/derp/exception/
  phabricator/src/applications/derp/query/
  phabricator/src/applications/derp/replyhandler/
  phabricator/src/applications/derp/storage/
  phabricator/src/applications/derp/view/

(The following two folders are also likely to be included for JavaScript and
CSS respectively. However, static resources are largely outside the scope of
this document. See @{article:Adding New CSS and JS}.)

  phabricator/webroot/rsrc/js/application/derp/
  phabricator/webroot/rsrc/css/application/derp/

These directories under ##phabricator/src/applications/derp/## represent
the basic set of class types from which most Phabrictor applications are
assembled. Each would contain a class file. For ##Derp##, these classes could be
something like:

 - **DerpConstants**: constants used in the ##Derp## application.
 - **DerpController**: business logic providing functionality for a given
   URI. Typically, controllers load data via Storage or Query classes, then
   present the data to the user via one or more View classes.
 - **DerpEditor**:  business logic for workflows that change one or more
   Storage objects. Editor classes are only necessary for particularly
   complicated edits and should be used pragmatically versus Storage objects.
 - **DerpException**: exceptions used in the ##Derp## application.
 - **DerpQuery**: query one or more storage objects for pertinent ##Derp##
   application data.  @{class:PhabricatorOffsetPagedQuery} is particularly
   handy for pagination and works well with @{class:AphrontPagerView}.
 - **DerpReplyHandler**: business logic from any configured email interactions
   users can have with the ##Derp## application.
 - **DerpStorage**: storage objects for the ##Derp## application. Typically
   there is a base class which extends @{class:PhabricatorLiskDAO} to configure
   application-wide storage settings like the application (thus database) name.
   Reading more about the @{class:LiskDAO} is highly recommended.
 - **DerpView**: view objects for the ##Derp## application. Typically these
   extend @{class:AphrontView}.
 - **ConduitAPI_derp_Method**: provides any and all ##Derp## application
   functionality that is accessible over Conduit.

However, it is likely that ##Derp## is even more complex, and rather than
containing one class, each directory has several classes. A typical example
happens around the CRUD of an object:

 - **DerpBaseController**: typically extends @{class:PhabricatorController},
   implements ##buildStandardPageResponse## with the ##Derp## application name
   and other ##Derp##-specific meta-data, and contains any controller-specific
   functionality used throughout the ##Derp## application.
 - **DerpDeleteController**: typically extends ##DerpBaseController## and
   presents a confirmation dialogue to the user about deleting a ##Derp##.
 - **DerpEditController**: typically extends ##DerpBaseController## and
   presents a form to create and edit ##Derps##. Most likely uses
   @{class:AphrontFormView} and various ##AphrontFormXControl## classes such as
   @{class:AphrontFormTextControl} to create the form.
 - **DerpListController**: typically extends ##DerpBaseController## and displays
   a set of one or more ##Derps##. Might use @{class:AphrontTableView} to create
   a table of ##Derps##.
 - **DerpViewController**: typically extends ##DerpBaseController## and displays
   a single ##Derp##.

Some especially awesome directories might have a ##__tests__## subdirectory
containing all pertinent unit test code for the class.

= Next Steps =

 - Learn about @{article:Adding New CSS and JS}; or
 - learn about the @{class:LiskDAO}; or
 - learn about @{article:Writing Unit Tests}; or
 - learn how to contribute (see @{article:Contributor Introduction}).
