docs: Apply sentence single-spacing from Prettier.

Signed-off-by: Anders Kaseorg <anders@zulip.com>
(cherry picked from commit 35c1c8d41b)
This commit is contained in:
Anders Kaseorg
2021-08-20 12:53:28 -07:00
committed by Tim Abbott
parent 0147c6adce
commit aa6e70382d
104 changed files with 1528 additions and 1528 deletions

View File

@@ -22,7 +22,7 @@ will also be helpful to review when creating a new feature. Many
aspects of the structure will be familiar to Django developers. Visit
[Django's documentation](https://docs.djangoproject.com/en/2.2/#index-first-steps)
for more information about how Django projects are typically
organized. And finally, the
organized. And finally, the
[message sending](../subsystems/sending-messages.md) documentation on
the additional complexity involved in sending messages.
@@ -199,8 +199,8 @@ dictionary.
```
**The majority of realm settings can be included in
`property_types`.** However, there are some properties that need custom
logic and thus cannot use this framework. For example:
`property_types`.** However, there are some properties that need custom
logic and thus cannot use this framework. For example:
- The realm `authentication_methods` attribute is a bitfield and needs
additional code for validation and updating.
@@ -255,7 +255,7 @@ Like typical apps, we will need our backend to update the database and
send some response to the client that made the request.
Beyond that, we need to orchestrate notifications about the setting change
to *other* clients (or other users, if you will). Clients
to *other* clients (or other users, if you will). Clients
find out about settings through two closely related code paths. When a client
first contacts the server, the server sends the client its
initial state. Subsequently, clients subscribe to "events," which can
@@ -481,7 +481,7 @@ write automated backend tests for your new feature.
To test the new setting syncs correctly with the `property_types`
framework, one usually just needs to add a line in each of
`test_events.py` and `test_realm.py` with a list of values to switch
between in the test. In the case of a boolean field, no action is
between in the test. In the case of a boolean field, no action is
required, because those tests will correctly assume that the only
values to test are `True` and `False`.
@@ -541,7 +541,7 @@ In frontend, we have split the `property_types` into three objects:
- `org_settings`: This contains properties for the "organization
settings" page. Settings belonging to this section generally
decide what features should be available to a user like deleting a
message, message edit history etc. Our `mandatory_topics` feature
message, message edit history etc. Our `mandatory_topics` feature
belongs in this section.
- `org_permissions`: This contains properties for the "organization
@@ -560,7 +560,7 @@ before implementing it.*
Note that some settings, like `realm_msg_edit_limit_setting`,
require special treatment, because they don't match the common
pattern. We can't extract the property name and compare the value of
pattern. We can't extract the property name and compare the value of
such input elements with those in `page_params`, so we have to
manually handle such situations in a couple key functions:
@@ -570,7 +570,7 @@ manually handle such situations in a couple key functions:
compare and set the values of corresponding DOM element.
- `settings_org.update_dependent_subsettings`: This handles settings
whose value and state depend on other elements. For example,
whose value and state depend on other elements. For example,
`realm_waiting_period_threshold` is only shown for with the right
state of `realm_waiting_period_setting`.
@@ -586,7 +586,7 @@ backend, so no UI updates are required.).
However, if you had written a function to update the UI after a given
setting has changed, your function should be referenced in the
`realm_settings` of `server_events_dispatch.js`. See for example
`realm_settings` of `server_events_dispatch.js`. See for example
`settings_emoji.update_custom_emoji_ui`.
``` diff
@@ -619,7 +619,7 @@ Here are few important cases you should consider when testing your changes:
properly.
- If your setting is dependent on another setting, carefully check
that both are properly synchronized. For example, the input element
that both are properly synchronized. For example, the input element
for `realm_waiting_period_threshold` is shown only when we have
selected the custom time limit option in the
`realm_waiting_period_setting` dropdown.

View File

@@ -76,7 +76,7 @@ Some titles have been shortened for organizational purposes.
*Tutorial* - [clean-code-javascript Software engineering principles](https://github.com/ryanmcdermott/clean-code-javascript)
*Course* - [React native and redux course](https://www.udemy.com/course/the-complete-react-native-and-redux-course/) (*Not free!*)
*Course* - [React native and redux course](https://www.udemy.com/course/the-complete-react-native-and-redux-course/) (*Not free!*)
*Slides* - [TypeScript vs. CoffeeScript vs. ES6](https://www.slideshare.net/NeilGreen1/type-script-vs-coffeescript-vs-es6)

View File

@@ -300,11 +300,11 @@ $ /usr/bin/env python3 ./my_program.py
The purpose of `/usr/bin/env` in our shebangs is as a way to locate
the `python3` program in your current environment, the same one the
shell would use if you ran `python3 my_program.py`. You may see
shell would use if you ran `python3 my_program.py`. You may see
Python scripts outside of Zulip with a shebang like
`#!/usr/bin/python3`; but because of the way Python virtualenvs work,
this has the effect of running the script outside of any currently
activated virtualenv. We use `/usr/bin/env` to keep our scripts
activated virtualenv. We use `/usr/bin/env` to keep our scripts
running inside the virtualenv where we've installed all our
dependencies.

View File

@@ -84,7 +84,7 @@ valid session cookie) before providing the view for this route, or
redirects the browser to a login page. This is used in the root path
(`/`) of the website for the web client. If a request comes from a
browser without a valid session cookie, they are redirected to a login
page. It is a small fork of Django's
page. It is a small fork of Django's
[login_required][login-required-link], adding a few extra checks
specific to Zulip.
@@ -104,7 +104,7 @@ Templates for the main website are found in
## Writing API REST endpoints
These are code-parseable views that take x-www-form-urlencoded or JSON
request bodies, and return JSON-string responses. Almost all Zulip
request bodies, and return JSON-string responses. Almost all Zulip
view code is in the implementations of API REST endpoints.
The REST API does authentication of the user through `rest_dispatch`,
@@ -124,9 +124,9 @@ string given via HTTP basic auth for API clients.
### Request variables
Most API views will have some arguments that are passed as part of the
request to control the behavior of the view. In any well-engineered
request to control the behavior of the view. In any well-engineered
view, you need to write code to parse and validate that the arguments
exist and have the correct form. For many applications, this leads to
exist and have the correct form. For many applications, this leads to
one of several bad outcomes:
- The code isn't written, so arguments aren't validated, leading to
@@ -139,7 +139,7 @@ one of several bad outcomes:
In Zulip, we solve this problem with a the special decorator called
`has_request_variables` which allows a developer to declare the
arguments a view function takes and validate their types all within
the `def` line of the function. We like this framework because we
the `def` line of the function. We like this framework because we
have found it makes the validation code compact, readable, and
conveniently located in the same place as the method it is validating
arguments for.
@@ -158,11 +158,11 @@ def create_user_backend(request, user_profile, email=REQ(), password=REQ(),
```
You will notice the special `REQ()` in the keyword arguments to
`create_user_backend`. `has_request_variables` parses the declared
`create_user_backend`. `has_request_variables` parses the declared
keyword arguments of the decorated function, and for each that has an
instance of `REQ` as the default value, it extracts the HTTP parameter
with that name from the request, parses it as JSON, and passes it to
the function. It will return an nicely JSON formatted HTTP 400 error
the function. It will return an nicely JSON formatted HTTP 400 error
in the event that an argument is missing, doesn't parse as JSON, or
otherwise is invalid.
@@ -194,7 +194,7 @@ REQ also helps us with request variable validation. For example:
not automatically marshall the input from JSON).
- Since there is no need to JSON-encode strings, usually simply
`my_string=REQ()` is correct. One can pass e.g.
`my_string=REQ()` is correct. One can pass e.g.
`str_validator=check_string_in(...)` where one wants to run a
validator on the value of a string.
@@ -205,7 +205,7 @@ for more validators and their documentation.
### Deciding which HTTP verb to use
When writing a new API view, you should writing a view to do just one
type of thing. Usually that's either a read or write operation.
type of thing. Usually that's either a read or write operation.
If you're reading data, GET is the best option. Other read-only verbs
are HEAD, which should be used for testing if a resource is available to
@@ -243,18 +243,18 @@ change the server more than once or cause unwanted side effects.
### Making changes to the database
If the view does any modification to the database, that change is done
in a helper function in `zerver/lib/actions.py`. Those functions are
in a helper function in `zerver/lib/actions.py`. Those functions are
responsible for doing a complete update to the state of the server,
which often entails both updating the database and sending any events
to notify clients about the state change. When possible, we prefer to
to notify clients about the state change. When possible, we prefer to
design a clean boundary between the view function and the actions
function is such that all user input validation happens in the view
code (i.e. all 400 type errors are thrown there), and the actions code
is responsible for atomically executing the change (this is usually
signalled by having the actions function have a name starting with
`do_`. So in most cases, errors in an actions function will be the
`do_`. So in most cases, errors in an actions function will be the
result of an operational problem (e.g. lost connection to the
database) and lead to a 500 error. If an actions function is
database) and lead to a 500 error. If an actions function is
responsible for validation as well, it should have a name starting
with `check_`.