mirror of
https://we.phorge.it/source/phorge.git
synced 2024-11-10 00:42:41 +01:00
Add a phabricator code layout doc
Summary: tried to cover the basics and sprinkle in lots of class references, etc. would really appreciate feedback...! :D Test Plan: read the docs! Reviewers: epriestley, vrana Reviewed By: vrana CC: aran Maniphest Tasks: T359 Differential Revision: https://secure.phabricator.com/D2223
This commit is contained in:
parent
4af3bb9f4b
commit
9bfb28253e
1 changed files with 128 additions and 0 deletions
128
src/docs/developer/phabricator_code_layout.diviner
Normal file
128
src/docs/developer/phabricator_code_layout.diviner
Normal file
|
@ -0,0 +1,128 @@
|
||||||
|
@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:
|
||||||
|
|
||||||
|
/path/to/arcanist/scripts/phutil_mapper.php /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}.
|
||||||
|
|
||||||
|
plus an auto-generated ##__init__.php## file.
|
||||||
|
|
||||||
|
NOTE: ##__init.php__## files are generated and maintained via `arc lint`.
|
||||||
|
|
||||||
|
If ##Derp## were (relatively) complex, one could reasonably expect to see
|
||||||
|
the following directory layout:
|
||||||
|
|
||||||
|
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/
|
||||||
|
phabricator/src/applications/conduit/method/derp/
|
||||||
|
|
||||||
|
(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/rsc/js/application/derp/
|
||||||
|
phabricator/webroot/rsc/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 and an ##__init__.php## 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 verus 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 a class and an ##__init__.php## file, each directory has
|
||||||
|
subdirectories of its own. A typical example happens around the CRUD of an
|
||||||
|
object:
|
||||||
|
|
||||||
|
phbaricator/src/application/derp/controller/base/
|
||||||
|
phabricator/src/application/derp/controller/delete/
|
||||||
|
phabricator/src/application/derp/controller/edit/
|
||||||
|
phabricator/src/application/derp/controller/list/
|
||||||
|
phabricator/src/application/derp/controller/view/
|
||||||
|
|
||||||
|
Which would then each contain a class and an ##__init__.php## file mapping to
|
||||||
|
corresponding classes
|
||||||
|
|
||||||
|
- **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##.
|
||||||
|
|
||||||
|
NOTE: each directory will have a class file with an ##__init__.php## or
|
||||||
|
subdirectories; never both.
|
||||||
|
|
||||||
|
= Next Steps =
|
||||||
|
|
||||||
|
- Learn about @{article:Adding New CSS and JS}; or
|
||||||
|
- learn about the @{class:LiskDAO}; or
|
||||||
|
- learn how to contribute (see @{article:Contributor Introduction}).
|
Loading…
Reference in a new issue