mirror of
https://github.com/zulip/zulip.git
synced 2025-10-24 16:43:57 +00:00
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:
committed by
Tim Abbott
parent
0147c6adce
commit
aa6e70382d
@@ -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.
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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.
|
||||
|
||||
|
||||
@@ -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_`.
|
||||
|
||||
|
||||
Reference in New Issue
Block a user