diff --git a/src/docs/contributor/adding_new_css_and_js.diviner b/src/docs/contributor/adding_new_css_and_js.diviner index 1f5fd94ac6..00a3808fba 100644 --- a/src/docs/contributor/adding_new_css_and_js.diviner +++ b/src/docs/contributor/adding_new_css_and_js.diviner @@ -18,8 +18,7 @@ To add a new CSS or JS file, create it in an appropriate location in `webroot/rsrc/css/` or `webroot/rsrc/js/` inside your `phabricator/` directory. -Each file must ##@provides## itself as a component, declared in a header -comment: +Each file must `@provides` itself as a component, declared in a header comment: LANG=css /** diff --git a/src/docs/contributor/darkconsole.diviner b/src/docs/contributor/darkconsole.diviner index cf512710c6..cddef89422 100644 --- a/src/docs/contributor/darkconsole.diviner +++ b/src/docs/contributor/darkconsole.diviner @@ -37,7 +37,7 @@ can use them to access different debugging and performance features. = Plugin: Error Log = The "Error Log" plugin shows errors that occurred while generating the page, -similar to the httpd ##error.log##. You can send information to the error log +similar to the httpd `error.log`. You can send information to the error log explicitly with the @{function@libphutil:phlog} function. If errors occurred, a red dot will appear on the plugin tab. diff --git a/src/docs/contributor/javascript_coding_standards.diviner b/src/docs/contributor/javascript_coding_standards.diviner index 65e15e6b55..3b47a566a6 100644 --- a/src/docs/contributor/javascript_coding_standards.diviner +++ b/src/docs/contributor/javascript_coding_standards.diviner @@ -18,9 +18,9 @@ guidelines, you can probably get away with skimming this document. - Use two spaces for indentation. Don't use literal tab characters. - Use Unix linebreaks ("\n"), not MSDOS ("\r\n") or OS9 ("\r"). - - Put a space after control keywords like ##if## and ##for##. + - Put a space after control keywords like `if` and `for`. - Put a space after commas in argument lists. - - Put space around operators like ##=##, ##<##, etc. + - Put space around operators like `=`, `<`, etc. - Don't put spaces after function names. - Parentheses should hug their contents. - Generally, prefer to wrap code at 80 columns. @@ -30,26 +30,26 @@ guidelines, you can probably get away with skimming this document. The Javascript language unambiguously dictates casing/naming rules; follow those rules. - - Name variables using ##lowercase_with_underscores##. - - Name classes using ##UpperCamelCase##. - - Name methods and properties using ##lowerCamelCase##. - - Name global functions using ##lowerCamelCase##. Avoid defining global + - Name variables using `lowercase_with_underscores`. + - Name classes using `UpperCamelCase`. + - Name methods and properties using `lowerCamelCase`. + - Name global functions using `lowerCamelCase`. Avoid defining global functions. - - Name constants using ##UPPERCASE##. - - Write ##true##, ##false##, and ##null## in lowercase. + - Name constants using `UPPERCASE`. + - Write `true`, `false`, and `null` in lowercase. - "Internal" methods and properties should be prefixed with an underscore. For more information about what "internal" means, see **Leading Underscores**, below. = Comments = - - Strongly prefer ##//## comments for making comments inside the bodies of + - Strongly prefer `//` comments for making comments inside the bodies of functions and methods (this lets someone easily comment out a block of code while debugging later). = Javascript Language = - - Use ##[]## and ##{}##, not ##new Array## and ##new Object##. + - Use `[]` and `{}`, not `new Array` and `new Object`. - When creating an object literal, do not quote keys unless required. = Examples = @@ -66,7 +66,7 @@ rules. } You should always put braces around the body of an if clause, even if it is only -one line. Note that operators like ##>## and ##===## are also surrounded by +one line. Note that operators like `>` and `===` are also surrounded by spaces. **for (iteration):** @@ -107,10 +107,10 @@ see @{article:Javascript Object and Array}. } `break` statements should be indented to block level. If you don't push them -in, you end up with an inconsistent rule for conditional ##break## statements, -as in the ##2## case. +in, you end up with an inconsistent rule for conditional `break` statements, +as in the `2` case. -If you insist on having a "fall through" case that does not end with ##break##, +If you insist on having a "fall through" case that does not end with `break`, make it clear in a comment that you wrote this intentionally. For instance: lang=js diff --git a/src/docs/contributor/n_plus_one.diviner b/src/docs/contributor/n_plus_one.diviner index 1f3b78424e..6d259671a1 100644 --- a/src/docs/contributor/n_plus_one.diviner +++ b/src/docs/contributor/n_plus_one.diviner @@ -14,11 +14,11 @@ The N+1 query problem is a common performance antipattern. It looks like this: // ... } -Assuming ##load_cats()## has an implementation that boils down to: +Assuming `load_cats()` has an implementation that boils down to: SELECT * FROM cat WHERE ... -..and ##load_hats_for_cat($cat)## has an implementation something like this: +..and `load_hats_for_cat($cat)` has an implementation something like this: SELECT * FROM hat WHERE catID = ... diff --git a/src/docs/contributor/phabricator_code_layout.diviner b/src/docs/contributor/phabricator_code_layout.diviner index 0b021d667b..d563d0e2e0 100644 --- a/src/docs/contributor/phabricator_code_layout.diviner +++ b/src/docs/contributor/phabricator_code_layout.diviner @@ -20,21 +20,21 @@ most of its code in standardized subdirectories and classes. = Best Practice Class and Subdirectory Organization = -Suppose you were working on the application ##Derp##. +Suppose you were working on the application `Derp`. phabricator/src/applications/derp/ -If ##Derp## were as simple as possible, it would have one subdirectory: +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 +containing the file `DerpController.php` with the class - - ##DerpController##: minimally implements a ##processRequest()## method + - `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 +If `Derp` were (relatively) complex, one could reasonably expect to see the following directory layout: phabricator/src/applications/derp/conduit/ @@ -54,54 +54,54 @@ 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 +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 +assembled. Each would contain a class file. For `Derp`, these classes could be something like: - - **DerpConstants**: constants used in the ##Derp## application. + - **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## + - **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 + 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 + - **DerpView**: view objects for the `Derp` application. Typically these extend @{class:AphrontView}. - - **DerpConduitAPIMethod**: provides any and all ##Derp## application + - **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 +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 + 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##. + - **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 +Some especially awesome directories might have a `__tests__` subdirectory containing all pertinent unit test code for the class. = Next Steps = diff --git a/src/docs/contributor/php_coding_standards.diviner b/src/docs/contributor/php_coding_standards.diviner index d79d340326..03f0bc158b 100644 --- a/src/docs/contributor/php_coding_standards.diviner +++ b/src/docs/contributor/php_coding_standards.diviner @@ -19,21 +19,21 @@ guidelines, you probably don't need to read this super thoroughly. - Use two spaces for indentation. Don't use tab literal characters. - Use Unix linebreaks ("\n"), not MSDOS ("\r\n") or OS9 ("\r"). - - Put a space after control keywords like ##if## and ##for##. + - Put a space after control keywords like `if` and `for`. - Put a space after commas in argument lists. - - Put a space around operators like ##=##, ##<##, etc. + - Put a space around operators like `=`, `<`, etc. - Don't put spaces after function names. - Parentheses should hug their contents. - Generally, prefer to wrap code at 80 columns. = Case and Capitalization = - - Name variables and functions using ##lowercase_with_underscores##. - - Name classes using ##UpperCamelCase##. - - Name methods and properties using ##lowerCamelCase##. + - Name variables and functions using `lowercase_with_underscores`. + - Name classes using `UpperCamelCase`. + - Name methods and properties using `lowerCamelCase`. - Use uppercase for common acronyms like ID and HTML. - - Name constants using ##UPPERCASE##. - - Write ##true##, ##false## and ##null## in lowercase. + - Name constants using `UPPERCASE`. + - Write `true`, `false` and `null` in lowercase. = Comments = @@ -43,9 +43,9 @@ guidelines, you probably don't need to read this super thoroughly. = PHP Language Style = - Use "" tag. - - Prefer casts like ##(string)## to casting functions like ##strval()##. - - Prefer type checks like ##$v === null## to type functions like - ##is_null()##. + - Prefer casts like `(string)` to casting functions like `strval()`. + - Prefer type checks like `$v === null` to type functions like + `is_null()`. - Avoid all crazy alternate forms of language constructs like "endwhile" and "<>". - Always put braces around conditional and loop blocks. diff --git a/src/docs/contributor/unit_tests.diviner b/src/docs/contributor/unit_tests.diviner index ac0d57e44d..3ac14b3e00 100644 --- a/src/docs/contributor/unit_tests.diviner +++ b/src/docs/contributor/unit_tests.diviner @@ -9,7 +9,7 @@ libphutil, Arcanist and Phabricator provide and use a simple unit test framework. This document is aimed at project contributors and describes how to use it to add and run tests in these projects or other libphutil libraries. -In the general case, you can integrate ##arc## with a custom unit test engine +In the general case, you can integrate `arc` with a custom unit test engine (like PHPUnit or any other unit testing library) to run tests in other projects. See @{article:Arcanist User Guide: Customizing Lint, Unit Tests and Workflows} for information on customizing engines. @@ -18,20 +18,20 @@ for information on customizing engines. To add new tests to a libphutil, Arcanist or Phabricator module: - - Create a ##__tests__/## directory in the module if it doesn't exist yet. - - Add classes to the ##__tests__/## directory which extend from + - Create a `__tests__/` directory in the module if it doesn't exist yet. + - Add classes to the `__tests__/` directory which extend from @{class:PhabricatorTestCase} (in Phabricator) or @{class@arcanist:PhutilTestCase} (elsewhere). - - Run ##arc liberate## on the library root so your classes are loadable. + - Run `arc liberate` on the library root so your classes are loadable. = Running Tests = Once you've added test classes, you can run them with: - - ##arc unit path/to/module/##, to explicitly run module tests. - - ##arc unit##, to run tests for all modules affected by changes in the + - `arc unit path/to/module/`, to explicitly run module tests. + - `arc unit`, to run tests for all modules affected by changes in the working copy. - - ##arc diff## will also run ##arc unit## for you. + - `arc diff` will also run `arc unit` for you. = Example Test Case = @@ -76,11 +76,11 @@ in a number of ways. From best to worst: is reasonable. - Build a real database simulation layer (fairly complex). - Disable isolation for a single test by using - ##LiskDAO::endIsolateAllLiskEffectsToCurrentProcess();## before your test - and ##LiskDAO::beginIsolateAllLiskEffectsToCurrentProcess();## after your + `LiskDAO::endIsolateAllLiskEffectsToCurrentProcess();` before your test + and `LiskDAO::beginIsolateAllLiskEffectsToCurrentProcess();` after your test. This will disable isolation for one test. NOT RECOMMENDED. - Disable isolation for your entire test case by overriding - ##getPhabricatorTestCaseConfiguration()## and providing - ##self::PHABRICATOR_TESTCONFIG_ISOLATE_LISK => false## in the configuration + `getPhabricatorTestCaseConfiguration()` and providing + `self::PHABRICATOR_TESTCONFIG_ISOLATE_LISK => false` in the configuration dictionary you return. This will disable isolation entirely. STRONGLY NOT RECOMMENDED. diff --git a/src/docs/contributor/using_oauthserver.diviner b/src/docs/contributor/using_oauthserver.diviner index dc8b377671..ff6f33a0c1 100644 --- a/src/docs/contributor/using_oauthserver.diviner +++ b/src/docs/contributor/using_oauthserver.diviner @@ -105,7 +105,7 @@ https://phabricator.example.com/api/user.whoami?access_token=ykc7ly7vtibj334oga4 If the token has expired or is otherwise invalid, the client will receive an error indicating as such. In these cases, the client should re-initiate -the entire ##Authorization Code Grant## flow. +the entire `Authorization Code Grant` flow. NOTE: See "Scopes" section below for more information on what data is currently exposed through the OAuth Server. diff --git a/src/docs/flavor/javascript_object_array.diviner b/src/docs/flavor/javascript_object_array.diviner index cf7e3371e6..cdba029e9a 100644 --- a/src/docs/flavor/javascript_object_array.diviner +++ b/src/docs/flavor/javascript_object_array.diviner @@ -8,7 +8,7 @@ behavior. = Primitives = Javascript has two native datatype primitives, Object and Array. Both are -classes, so you can use ##new## to instantiate new objects and arrays: +classes, so you can use `new` to instantiate new objects and arrays: COUNTEREXAMPLE var a = new Array(); // Not preferred. @@ -42,7 +42,7 @@ and Array are both classes, but "object" is also a primitive type. Object is = Objects are Maps, Arrays are Lists = -PHP has a single ##array## datatype which behaves like as both map and a list, +PHP has a single `array` datatype which behaves like as both map and a list, and a common mistake is to treat Javascript arrays (or objects) in the same way. **Don't do this.** It sort of works until it doesn't. Instead, learn how Javascript's native datatypes work and use them properly. @@ -94,9 +94,9 @@ Iterate over a list like this: NOTE: There's some sparse array nonsense being omitted here, see below. -If you try to use ##for (var k in ...)## syntax to iterate over an Array, you'll +If you try to use `for (var k in ...)` syntax to iterate over an Array, you'll pick up a whole pile of keys you didn't intend to and it won't work. If you try -to use ##for (var ii = 0; ...)## syntax to iterate over an Object, it won't work +to use `for (var ii = 0; ...)` syntax to iterate over an Object, it won't work at all. If you consistently treat Arrays as lists and Objects as maps and use the @@ -106,7 +106,7 @@ way. = hasOwnProperty() = An issue with this model is that if you write stuff to Object.prototype, it will -show up every time you use enumeration ##for##: +show up every time you use enumeration `for`: COUNTEREXAMPLE var o = {}; @@ -117,7 +117,7 @@ show up every time you use enumeration ##for##: There are two ways to avoid this: - - test that ##k## exists on ##o## by calling ##o.hasOwnProperty(k)## in every + - test that `k` exists on `o` by calling `o.hasOwnProperty(k)` in every single loop everywhere in your program and only use libraries which also do this and never forget to do it ever; or - don't write to Object.prototype. diff --git a/src/docs/flavor/javascript_pitfalls.diviner b/src/docs/flavor/javascript_pitfalls.diviner index beef1b83e6..9276ae4712 100644 --- a/src/docs/flavor/javascript_pitfalls.diviner +++ b/src/docs/flavor/javascript_pitfalls.diviner @@ -27,7 +27,7 @@ insert semicolons after each statement. You should also prefer to break lines in places where insertion of a semicolon would not make the unparseable parseable, usually after operators. -= ##with## is Bad News = += `with` is Bad News = `with` is a pretty bad feature, for this reason among others: @@ -35,12 +35,12 @@ usually after operators. property = 3; // Might be on object, might be on window: who knows. } -Avoid ##with##. +Avoid `with`. -= ##arguments## is not an Array = += `arguments` is not an Array = -You can convert ##arguments## to an array using JX.$A() or similar. Note that -you can pass ##arguments## to Function.prototype.apply() without converting it. +You can convert `arguments` to an array using JX.$A() or similar. Note that +you can pass `arguments` to Function.prototype.apply() without converting it. = Object, Array, and iteration are needlessly hard = @@ -82,6 +82,6 @@ objects and can have methods and properties, and inherit from Array.prototype, Number.prototype, etc.) and their logical behavior is at best absurd and at worst strictly wrong. -**Never use** ##new Number()##, ##new String()## or ##new Boolean()## unless +**Never use** `new Number()`, `new String()` or `new Boolean()` unless your Javascript is God Tier and you are absolutely sure you know what you are doing. diff --git a/src/docs/flavor/php_pitfalls.diviner b/src/docs/flavor/php_pitfalls.diviner index 2b8373f8cc..09e0f108f0 100644 --- a/src/docs/flavor/php_pitfalls.diviner +++ b/src/docs/flavor/php_pitfalls.diviner @@ -31,7 +31,7 @@ complex variables safely. = isset(), empty() and Truthiness = -A value is "truthy" if it evaluates to true in an ##if## clause: +A value is "truthy" if it evaluates to true in an `if` clause: $value = something(); if ($value) { @@ -61,7 +61,7 @@ This is wrong because it prevents users from making the comment "0". //THIS COMMENT IS TOTALLY AWESOME AND I MAKE IT ALL THE TIME SO YOU HAD BETTER NOT BREAK IT!!!// A better test is probably strlen(). -In addition to truth tests with ##if##, PHP has two special truthiness operators +In addition to truth tests with `if`, PHP has two special truthiness operators which look like functions but aren't: empty() and isset(). These operators help deal with undeclared variables. @@ -147,12 +147,12 @@ In a libphutil environment, you can often do this easily with These functions are much slower for even moderately large inputs than array_intersect_key() and array_diff_key(), because they can not make the -assumption that their inputs are unique scalars as the ##key## varieties can. -Strongly prefer the ##key## varieties. +assumption that their inputs are unique scalars as the `key` varieties can. +Strongly prefer the `key` varieties. = array_uintersect() and array_udiff() are Definitely Slow Too = -These functions have the problems of both the ##usort()## family and the +These functions have the problems of both the `usort()` family and the `array_diff()` family. Avoid them. = foreach() Does Not Create Scope = @@ -205,7 +205,7 @@ emerge unmodified. That is, if you have a function that takes references: $x = 41; call_user_func('add_one', $x); -...##$x## will not be modified. The solution is to use call_user_func_array() +...`$x` will not be modified. The solution is to use call_user_func_array() and wrap the reference in an array: $x = 41; @@ -243,7 +243,7 @@ dictionary (vs a list) when passed to json_encode(). = Invoking "new" With an Argument Vector is Really Hard = -If you have some ##$class_name## and some ##$argv## of constructor +If you have some `$class_name` and some `$argv` of constructor arguments and you want to do this: new $class_name($argv[0], $argv[1], ...); diff --git a/src/docs/flavor/recommendations_on_revision_control.diviner b/src/docs/flavor/recommendations_on_revision_control.diviner index 0cb0eb5e6c..8e30e2f4f1 100644 --- a/src/docs/flavor/recommendations_on_revision_control.diviner +++ b/src/docs/flavor/recommendations_on_revision_control.diviner @@ -24,11 +24,11 @@ master/remote version of the repository. Specifically, this means that an entire conceptual changeset ("add a foo widget") is represented in the remote as exactly one commit (in some form), not a sequence of checkpoint commits. - - In SVN, this means don't ##commit## until after an idea has been completely + - In SVN, this means don't `commit` until after an idea has been completely written. All reasonable SVN workflows naturally enforce this. - - In Git, this means squashing checkpoint commits as you go (with ##git commit - --amend##) or before pushing (with ##git rebase -i## or ##git merge - --squash##), or having a strict policy where your master/trunk contains only + - In Git, this means squashing checkpoint commits as you go (with `git commit + --amend`) or before pushing (with `git rebase -i` or `git merge + --squash`), or having a strict policy where your master/trunk contains only merge commits and each is a merge between the old master and a branch which represents a single idea. Although this preserves the checkpoint commits along the branches, you can view master alone as a series of single-idea diff --git a/src/docs/flavor/soon_static_resources.diviner b/src/docs/flavor/soon_static_resources.diviner index 78820c5081..96f28cfe2f 100644 --- a/src/docs/flavor/soon_static_resources.diviner +++ b/src/docs/flavor/soon_static_resources.diviner @@ -84,7 +84,7 @@ eventually moved to automatic generation based on production data. = Caches and Serving Content = In the simplest implementation of static resources, you write out a raw JS tag -with something like ##src="/js/base.js"##. This will break disastrously as you +with something like `src="/js/base.js"`. This will break disastrously as you scale, because clients will be running with stale versions of resources. There are bunch of subtle problems (especially once you have a CDN), but the big one is that if a user is browsing your site as you push/deploy, their client will diff --git a/src/docs/tech/celerity.diviner b/src/docs/tech/celerity.diviner index 91a53d6e8d..e1b744645b 100644 --- a/src/docs/tech/celerity.diviner +++ b/src/docs/tech/celerity.diviner @@ -29,7 +29,7 @@ Celerity's primary API is @{function:require_celerity_resource}, which marks a resource for inclusion when a response is rendered (e.g., when the HTML page is generated, or when the response to an Ajax request is built). For instance, if you use a CSS class like "widget-view", you must ensure the appropriate CSS is -included by calling ##require_celerity_resource('widget-view-css')## (or +included by calling `require_celerity_resource('widget-view-css')` (or similar), at your use site. This function uses @{class:CelerityAPI} to access the active @@ -48,14 +48,14 @@ and not all of its dependencies) and any packaging rules (so it may be able to generate fewer resource requests, improving performance). It then generates `