@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. 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 Phabricator 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}. - **DerpConduitAPIMethod**: 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} 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}).